diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml new file mode 100644 index 000000000..6055bab01 --- /dev/null +++ b/.github/workflows/pull_request.yml @@ -0,0 +1,39 @@ +name: build_and_test +on: + pull_request: + workflow_dispatch: +concurrency: + group: "${{ github.ref }}" + cancel-in-progress: true +jobs: + build: + runs-on: macos-13 + env: + TEST_RUNNER_PIA_TEST_USER: ${{ secrets.PIA_ACCOUNT_USERNAME}} + TEST_RUNNER_PIA_TEST_PASSWORD: ${{ secrets.PIA_ACCOUNT_PASSWORD }} + + steps: + - name: Setup Git credentials + run: | + git config --global url."https://${{ secrets.ORG_GITHUB_USERNAME }}:${{ secrets.ORG_GITHUB_TOKEN }}@github.com/".insteadOf "git@github.com:" + + - uses: actions/checkout@v3 + + - name: Select XCode version + run: sudo xcode-select -s /Applications/Xcode_15.0.app + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.0.2 + + - name: Install Fastlane + run: gem install fastlane + + - name: Run unit tests + run: bundle exec fastlane tests + + - name: Run e2e tests + run: bundle exec fastlane e2e_tests + + \ No newline at end of file diff --git a/.github/workflows/testflight_deploy.yml b/.github/workflows/testflight_deploy.yml new file mode 100644 index 000000000..16d82f888 --- /dev/null +++ b/.github/workflows/testflight_deploy.yml @@ -0,0 +1,51 @@ +name: testflight_deploy +on: + push: + branches: + - master + + workflow_dispatch: +concurrency: + group: "${{ github.ref }}" + cancel-in-progress: true +jobs: + build: + runs-on: macos-13 + env: + CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATE_PASSWORD }} + KEYCHAIN_NAME: ${{ secrets.KEYCHAIN_NAME }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} + APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} + APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }} + + steps: + - name: Setup Git credentials + run: | + git config --global url."https://${{ secrets.ORG_GITHUB_USERNAME }}:${{ secrets.ORG_GITHUB_TOKEN }}@github.com/".insteadOf "git@github.com:" + + - uses: actions/checkout@v3 + + - name: Select XCode version + run: sudo xcode-select -s /Applications/Xcode_15.0.app + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.0.2 + + - name: Install Fastlane + run: gem install fastlane + + - name: Decode Certificates + run: echo "${{ secrets.IOS_CERTIFICATE }}" | base64 --decode > ./fastlane/Certificate.p12 + + - name: Run tests + run: bundle exec fastlane tests + + - name: Set up certificates and profiles + run: bundle exec fastlane get_profiles > /dev/null 2>&1 + + - name: Upload version to TestFlight + run: bundle exec fastlane testflight_build + \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..7a118b49b --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "fastlane" diff --git a/PIA VPN Tunnel/PacketTunnelProvider.swift b/PIA VPN Tunnel/PacketTunnelProvider.swift index 36c8eb1d4..67aa1e0c5 100644 --- a/PIA VPN Tunnel/PacketTunnelProvider.swift +++ b/PIA VPN Tunnel/PacketTunnelProvider.swift @@ -20,7 +20,7 @@ // Internet Access iOS Client. If not, see . // -import TunnelKit +import TunnelKitOpenVPNAppExtension class PacketTunnelProvider: OpenVPNTunnelProvider { } diff --git a/PIA VPN UITests/Credentials.plist b/PIA VPN UITests/Credentials.plist new file mode 100644 index 000000000..e256b0454 --- /dev/null +++ b/PIA VPN UITests/Credentials.plist @@ -0,0 +1,17 @@ + + + + + expired + + valid + + invalid + + username + random.username + password + passWord@533 + + + diff --git a/PIA VPN UITests/CredentialsUtil.swift b/PIA VPN UITests/CredentialsUtil.swift new file mode 100644 index 000000000..82d372ea4 --- /dev/null +++ b/PIA VPN UITests/CredentialsUtil.swift @@ -0,0 +1,47 @@ +// +// CredentialsUtil.swift +// PIA VPN +// +// Created by Waleed Mahmood on 08.03.22. +// Copyright © 2022 Private Internet Access Inc. All rights reserved. +// + +import Foundation + +public enum CredentialsType: String { + case valid = "valid" + case expired = "expired" + case invalid = "invalid" +} + +public struct Credentials: Codable { + let username: String + let password: String + + init(from dictionary: Any) throws { + let data = try JSONSerialization.data(withJSONObject: dictionary, options: .prettyPrinted) + let decoder = JSONDecoder() + self = try decoder.decode(Self.self, from: data) + } +} + +public class CredentialsUtil { + public static func credentials(type: CredentialsType) -> Credentials { + let bundle = Bundle(for: CredentialsUtil.self) + guard let filePath = bundle.path(forResource: "Credentials", ofType: "plist") else { + fatalError("Couldn't find file 'Credentials.plist'") + } + + let plist = NSDictionary(contentsOfFile: filePath) + guard let dictionary = plist?.object(forKey: type.rawValue) as? [String: String] else { + fatalError("Couldn't find key '\(type.rawValue)' in 'Credentials.plist'") + } + + do { + return try Credentials(from: dictionary) + } + catch { +  fatalError("Credential file does not contain required information") + } + } +} diff --git a/PIA VPN UITests/PIALaunchTests.swift b/PIA VPN UITests/PIALaunchTests.swift new file mode 100644 index 000000000..fc904bb62 --- /dev/null +++ b/PIA VPN UITests/PIALaunchTests.swift @@ -0,0 +1,33 @@ +// +// PIALaunchTests.swift +// PIA VPN UITests +// +// Created by Waleed Mahmood on 01.03.22. +// Copyright © 2022 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +class PIALaunchTests: XCTestCase { + + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + + // Insert steps here to perform after app launch but before taking a screenshot, + // such as logging into a test account or navigating somewhere in the app + + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +} diff --git a/PIA VPN UITests/PIALoginTests.swift b/PIA VPN UITests/PIALoginTests.swift new file mode 100644 index 000000000..af87077ab --- /dev/null +++ b/PIA VPN UITests/PIALoginTests.swift @@ -0,0 +1,145 @@ +// +// PIALoginTests.swift +// PIA VPN UITests +// +// Created by Waleed Mahmood on 01.03.22. +// Copyright © 2022 Private Internet Access Inc. All rights reserved. +// + +import XCTest +import PIALibrary +import Pods_PIA_VPN_dev + +class PIALoginTests: XCTestCase { + + static let timeoutUIOps: TimeInterval = 10.0 + let app = XCUIApplication() + + override func setUpWithError() throws { + continueAfterFailure = false + app.launch() + navigateToGetStartedViewController() + } + + override func tearDownWithError() throws { + // when test finishes logout + navigateToGetStartedViewController() + } + + private func navigateToGetStartedViewController() { + // check if we have a side menu + if app.navigationBars.buttons[Accessibility.Id.Dashboard.menu].exists { + openSideMenuAndTapLogout() + } + } + + private func openSideMenuAndTapLogout() { + app.navigationBars.buttons[Accessibility.Id.Dashboard.menu].tap() + + if app.cells[Accessibility.Id.Menu.logout].waitForExistence(timeout: PIALoginTests.timeoutUIOps) { + app.cells[Accessibility.Id.Menu.logout].tap() + } else { + XCTAssert(false, "PIALoginTests:: A side menu is found but no logout cell is found") + } + if app.buttons[Accessibility.Id.Dialog.destructive].waitForExistence(timeout: PIALoginTests.timeoutUIOps) { + app.buttons[Accessibility.Id.Dialog.destructive].tap() + } else { + XCTAssert(false, "PIALoginTests:: Logout alert destructive button is not found") + } + } + + private func navigateToLoginViewController() { + var conversionSubviewVisible = false + + // wait for feature flags + var submitButtonExists = app.buttons[Accessibility.Id.Login.submit].waitForExistence(timeout: PIALoginTests.timeoutUIOps) + + // check if new button should be used + if !submitButtonExists { + submitButtonExists = app.buttons[Accessibility.Id.Login.submitNew].waitForExistence(timeout: PIALoginTests.timeoutUIOps) + conversionSubviewVisible = true + } + + if submitButtonExists { + if submitButtonExists && !conversionSubviewVisible { + app.buttons[Accessibility.Id.Login.submit].tap() + } else { + app.buttons[Accessibility.Id.Login.submitNew].tap() + } + + } else { + XCTAssert(false, "PIALoginTests:: One of the Login buttons on GetStartedViewController is either not identifiable or have been moved") + } + } + + private func fillLoginScreen(with credentials: Credentials) { + let usernameTextField = app.textFields[Accessibility.Id.Login.username] + let passwordTextField = app.secureTextFields[Accessibility.Id.Login.password] + + if usernameTextField.exists && passwordTextField.exists { + // Type username + usernameTextField.tap() + usernameTextField.typeText(credentials.username) + + // Type password + passwordTextField.tap() + passwordTextField.typeText(credentials.password) + } else { + XCTAssert(false, "PIALoginTests:: Username and Password text fields on LoginViewController are either not identifiable or are moved") + } + } + + private func loginUser(ofType: CredentialsType) { + navigateToLoginViewController() + switch ofType { + case .valid: + fillLoginScreen(with: CredentialsUtil.credentials(type: .valid)) + case .expired: + fillLoginScreen(with: CredentialsUtil.credentials(type: .expired)) + case .invalid: + fillLoginScreen(with: CredentialsUtil.credentials(type: .invalid)) + } + + let loginButton = app.buttons[Accessibility.Id.Login.submit] + loginButton.tap() + } + + func testInvalidUserLogin() throws { + loginUser(ofType: .invalid) + + let bannerViewExists = app.staticTexts["Your username or password is incorrect."].waitForExistence(timeout: PIALoginTests.timeoutUIOps) + XCTAssertTrue(bannerViewExists, "PIALoginTests::testInvalidUserLogin() failed") + } + + func testExpiredUserLogin() throws { + app.switchEnvironment(to: .staging) + loginUser(ofType: .expired) + + let bannerViewExists = app.staticTexts["Your username or password is incorrect."].waitForExistence(timeout: PIALoginTests.timeoutUIOps) + XCTAssertTrue(bannerViewExists, "PIALoginTests::testExpiredUserLogin() failed") + } + + func testValidUserLogin() throws { + app.switchEnvironment(to: .production) + loginUser(ofType: .valid) + + let viewTitleExists = app.staticTexts["PIA needs access to your VPN profiles to secure your traffic"].waitForExistence(timeout: PIALoginTests.timeoutUIOps) + let okButtonExist = app.buttons[Accessibility.Id.Permissions.submit].waitForExistence(timeout: PIALoginTests.timeoutUIOps) + XCTAssertTrue(viewTitleExists && okButtonExist, "PIALoginTests::testActiveUserLogin() failed") + } +} + +private extension XCUIApplication { + + func switchEnvironment(to environment: Client.Environment) { + // wait until the button is available + _ = self.buttons[Accessibility.Id.Welcome.environment].waitForExistence(timeout: PIALoginTests.timeoutUIOps) + let environmentButton = self.buttons[Accessibility.Id.Welcome.environment] + + if environmentButton.label.lowercased() != environment.rawValue.lowercased() { + + // then click it to switch environment + environmentButton.tap() + } + } +} diff --git a/PIA VPN UITests/PIAUITests.swift b/PIA VPN UITests/PIAUITests.swift new file mode 100644 index 000000000..c220431f0 --- /dev/null +++ b/PIA VPN UITests/PIAUITests.swift @@ -0,0 +1,43 @@ +// +// PIAUITests.swift +// PIA VPN UITests +// +// Created by Waleed Mahmood on 01.03.22. +// Copyright © 2022 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +class PIAUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testLaunchPerformance() throws { + if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } + } +} diff --git a/PIA VPN dev.app/ActiveDedicatedIpHeaderViewCell.nib b/PIA VPN dev.app/ActiveDedicatedIpHeaderViewCell.nib new file mode 100644 index 000000000..7efc384a6 Binary files /dev/null and b/PIA VPN dev.app/ActiveDedicatedIpHeaderViewCell.nib differ diff --git a/PIA VPN dev.app/AppIcon60x60@2x.png b/PIA VPN dev.app/AppIcon60x60@2x.png new file mode 100644 index 000000000..526a4566e Binary files /dev/null and b/PIA VPN dev.app/AppIcon60x60@2x.png differ diff --git a/PIA VPN dev.app/AppIcon76x76@2x~ipad.png b/PIA VPN dev.app/AppIcon76x76@2x~ipad.png new file mode 100644 index 000000000..8851ceed7 Binary files /dev/null and b/PIA VPN dev.app/AppIcon76x76@2x~ipad.png differ diff --git a/PIA VPN dev.app/Assets.car b/PIA VPN dev.app/Assets.car new file mode 100644 index 000000000..388508742 Binary files /dev/null and b/PIA VPN dev.app/Assets.car differ diff --git a/PIA VPN dev.app/Components.plist b/PIA VPN dev.app/Components.plist new file mode 100644 index 000000000..3f35ce2ff Binary files /dev/null and b/PIA VPN dev.app/Components.plist differ diff --git a/PIA VPN dev.app/ConnectionTile.nib b/PIA VPN dev.app/ConnectionTile.nib new file mode 100644 index 000000000..ba8af5dc7 Binary files /dev/null and b/PIA VPN dev.app/ConnectionTile.nib differ diff --git a/PIA VPN dev.app/ConnectionTileCollectionViewCell.nib/objects-12.3+.nib b/PIA VPN dev.app/ConnectionTileCollectionViewCell.nib/objects-12.3+.nib new file mode 100644 index 000000000..49a2badfd Binary files /dev/null and b/PIA VPN dev.app/ConnectionTileCollectionViewCell.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/ConnectionTileCollectionViewCell.nib/runtime.nib b/PIA VPN dev.app/ConnectionTileCollectionViewCell.nib/runtime.nib new file mode 100644 index 000000000..08ebc35c2 Binary files /dev/null and b/PIA VPN dev.app/ConnectionTileCollectionViewCell.nib/runtime.nib differ diff --git a/PIA VPN dev.app/CustomNetworkCollectionViewCell.nib/objects-12.3+.nib b/PIA VPN dev.app/CustomNetworkCollectionViewCell.nib/objects-12.3+.nib new file mode 100644 index 000000000..10e1c1f9e Binary files /dev/null and b/PIA VPN dev.app/CustomNetworkCollectionViewCell.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/CustomNetworkCollectionViewCell.nib/runtime.nib b/PIA VPN dev.app/CustomNetworkCollectionViewCell.nib/runtime.nib new file mode 100644 index 000000000..e0594f13b Binary files /dev/null and b/PIA VPN dev.app/CustomNetworkCollectionViewCell.nib/runtime.nib differ diff --git a/PIA VPN dev.app/DNS.plist b/PIA VPN dev.app/DNS.plist new file mode 100644 index 000000000..69f7717c8 Binary files /dev/null and b/PIA VPN dev.app/DNS.plist differ diff --git a/PIA VPN dev.app/DedicatedIPTitleHeaderViewCell.nib b/PIA VPN dev.app/DedicatedIPTitleHeaderViewCell.nib new file mode 100644 index 000000000..d2bd0e1f4 Binary files /dev/null and b/PIA VPN dev.app/DedicatedIPTitleHeaderViewCell.nib differ diff --git a/PIA VPN dev.app/DedicatedIpEmptyHeaderViewCell.nib b/PIA VPN dev.app/DedicatedIpEmptyHeaderViewCell.nib new file mode 100644 index 000000000..9c369c398 Binary files /dev/null and b/PIA VPN dev.app/DedicatedIpEmptyHeaderViewCell.nib differ diff --git a/PIA VPN dev.app/DedicatedIpRowViewCell.nib b/PIA VPN dev.app/DedicatedIpRowViewCell.nib new file mode 100644 index 000000000..05b881381 Binary files /dev/null and b/PIA VPN dev.app/DedicatedIpRowViewCell.nib differ diff --git a/PIA VPN dev.app/FavoriteServersTile.nib b/PIA VPN dev.app/FavoriteServersTile.nib new file mode 100644 index 000000000..03bef88e5 Binary files /dev/null and b/PIA VPN dev.app/FavoriteServersTile.nib differ diff --git a/PIA VPN dev.app/FavoriteServersTileCollectionViewCell.nib/objects-12.3+.nib b/PIA VPN dev.app/FavoriteServersTileCollectionViewCell.nib/objects-12.3+.nib new file mode 100644 index 000000000..ceb7dcb25 Binary files /dev/null and b/PIA VPN dev.app/FavoriteServersTileCollectionViewCell.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/FavoriteServersTileCollectionViewCell.nib/runtime.nib b/PIA VPN dev.app/FavoriteServersTileCollectionViewCell.nib/runtime.nib new file mode 100644 index 000000000..b226ba68e Binary files /dev/null and b/PIA VPN dev.app/FavoriteServersTileCollectionViewCell.nib/runtime.nib differ diff --git a/PIA VPN dev.app/Flags-dev.plist b/PIA VPN dev.app/Flags-dev.plist new file mode 100644 index 000000000..27b9171bb Binary files /dev/null and b/PIA VPN dev.app/Flags-dev.plist differ diff --git a/PIA VPN dev.app/Frameworks/PIACSI.framework/Info.plist b/PIA VPN dev.app/Frameworks/PIACSI.framework/Info.plist new file mode 100644 index 000000000..7695e7c28 --- /dev/null +++ b/PIA VPN dev.app/Frameworks/PIACSI.framework/Info.plist @@ -0,0 +1,31 @@ + + + + + CFBundleExecutable + PIACSI + CFBundleIdentifier + com.privateinternetaccess.csi.PIACSI + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + PIACSI + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSupportedPlatforms + + iPhoneOS + + CFBundleVersion + 1 + MinimumOSVersion + 9.0 + UIDeviceFamily + + 1 + 2 + + + diff --git a/PIA VPN dev.app/Frameworks/PIACSI.framework/PIACSI b/PIA VPN dev.app/Frameworks/PIACSI.framework/PIACSI new file mode 100755 index 000000000..a7a55545c Binary files /dev/null and b/PIA VPN dev.app/Frameworks/PIACSI.framework/PIACSI differ diff --git a/PIA VPN dev.app/Frameworks/PIACSI.framework/_CodeSignature/CodeResources b/PIA VPN dev.app/Frameworks/PIACSI.framework/_CodeSignature/CodeResources new file mode 100644 index 000000000..0adf83c91 --- /dev/null +++ b/PIA VPN dev.app/Frameworks/PIACSI.framework/_CodeSignature/CodeResources @@ -0,0 +1,101 @@ + + + + + files + + Info.plist + + pAgmhvOx+ttiJrsquW85U6Mc5aM= + + + files2 + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/Frameworks/PIAKPI.framework/Info.plist b/PIA VPN dev.app/Frameworks/PIAKPI.framework/Info.plist new file mode 100644 index 000000000..86b866f1e --- /dev/null +++ b/PIA VPN dev.app/Frameworks/PIAKPI.framework/Info.plist @@ -0,0 +1,31 @@ + + + + + CFBundleExecutable + PIAKPI + CFBundleIdentifier + com.privateinternetaccess.kpi.PIAKPI + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + PIAKPI + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSupportedPlatforms + + iPhoneOS + + CFBundleVersion + 1 + MinimumOSVersion + 9.0 + UIDeviceFamily + + 1 + 2 + + + diff --git a/PIA VPN dev.app/Frameworks/PIAKPI.framework/PIAKPI b/PIA VPN dev.app/Frameworks/PIAKPI.framework/PIAKPI new file mode 100755 index 000000000..3a4e1d8be Binary files /dev/null and b/PIA VPN dev.app/Frameworks/PIAKPI.framework/PIAKPI differ diff --git a/PIA VPN dev.app/Frameworks/PIAKPI.framework/_CodeSignature/CodeResources b/PIA VPN dev.app/Frameworks/PIAKPI.framework/_CodeSignature/CodeResources new file mode 100644 index 000000000..cd8cd22f9 --- /dev/null +++ b/PIA VPN dev.app/Frameworks/PIAKPI.framework/_CodeSignature/CodeResources @@ -0,0 +1,101 @@ + + + + + files + + Info.plist + + nvMD58Pn9TT2kC7Ifc0XZdJ1IQ0= + + + files2 + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/Frameworks/PIARegions.framework/Info.plist b/PIA VPN dev.app/Frameworks/PIARegions.framework/Info.plist new file mode 100644 index 000000000..0aaaf46c5 --- /dev/null +++ b/PIA VPN dev.app/Frameworks/PIARegions.framework/Info.plist @@ -0,0 +1,31 @@ + + + + + CFBundleExecutable + PIARegions + CFBundleIdentifier + com.privateinternetaccess.regions.PIARegions + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + PIARegions + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSupportedPlatforms + + iPhoneOS + + CFBundleVersion + 1 + MinimumOSVersion + 9.0 + UIDeviceFamily + + 1 + 2 + + + diff --git a/PIA VPN dev.app/Frameworks/PIARegions.framework/PIARegions b/PIA VPN dev.app/Frameworks/PIARegions.framework/PIARegions new file mode 100755 index 000000000..1c7b92b9d Binary files /dev/null and b/PIA VPN dev.app/Frameworks/PIARegions.framework/PIARegions differ diff --git a/PIA VPN dev.app/Frameworks/PIARegions.framework/_CodeSignature/CodeResources b/PIA VPN dev.app/Frameworks/PIARegions.framework/_CodeSignature/CodeResources new file mode 100644 index 000000000..5d49ffce8 --- /dev/null +++ b/PIA VPN dev.app/Frameworks/PIARegions.framework/_CodeSignature/CodeResources @@ -0,0 +1,101 @@ + + + + + files + + Info.plist + + 1tJ+m8+dw/cFodi2bzU5k7uPTJ4= + + + files2 + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/Frameworks/account.framework/Info.plist b/PIA VPN dev.app/Frameworks/account.framework/Info.plist new file mode 100644 index 000000000..6271ceb25 --- /dev/null +++ b/PIA VPN dev.app/Frameworks/account.framework/Info.plist @@ -0,0 +1,31 @@ + + + + + CFBundleExecutable + account + CFBundleIdentifier + com.privateinternetaccess.account.account + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + account + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSupportedPlatforms + + iPhoneOS + + CFBundleVersion + 1 + MinimumOSVersion + 9.0 + UIDeviceFamily + + 1 + 2 + + + diff --git a/PIA VPN dev.app/Frameworks/account.framework/_CodeSignature/CodeResources b/PIA VPN dev.app/Frameworks/account.framework/_CodeSignature/CodeResources new file mode 100644 index 000000000..ad8d979ca --- /dev/null +++ b/PIA VPN dev.app/Frameworks/account.framework/_CodeSignature/CodeResources @@ -0,0 +1,101 @@ + + + + + files + + Info.plist + + z+drOuEngEvNK0w6F0e1xAUTBU0= + + + files2 + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/Frameworks/account.framework/account b/PIA VPN dev.app/Frameworks/account.framework/account new file mode 100755 index 000000000..d01542744 Binary files /dev/null and b/PIA VPN dev.app/Frameworks/account.framework/account differ diff --git a/PIA VPN dev.app/Frameworks/openssl.framework/Info.plist b/PIA VPN dev.app/Frameworks/openssl.framework/Info.plist new file mode 100755 index 000000000..4dea0cd26 --- /dev/null +++ b/PIA VPN dev.app/Frameworks/openssl.framework/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + openssl + CFBundleIdentifier + org.openssl.OpenSSL + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + openssl + CFBundlePackageType + FMWK + CFBundleShortVersionString + 3.0.-4600 + CFBundleVersion + 1 + MinimumOSVersion + 12.0 + + diff --git a/PIA VPN dev.app/Frameworks/openssl.framework/_CodeSignature/CodeResources b/PIA VPN dev.app/Frameworks/openssl.framework/_CodeSignature/CodeResources new file mode 100644 index 000000000..f0f160d34 --- /dev/null +++ b/PIA VPN dev.app/Frameworks/openssl.framework/_CodeSignature/CodeResources @@ -0,0 +1,101 @@ + + + + + files + + Info.plist + + 5z4kgULU81dtbcBAWWUGf1TqMKs= + + + files2 + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/Frameworks/openssl.framework/openssl b/PIA VPN dev.app/Frameworks/openssl.framework/openssl new file mode 100755 index 000000000..eeed8a6e5 Binary files /dev/null and b/PIA VPN dev.app/Frameworks/openssl.framework/openssl differ diff --git a/PIA VPN dev.app/IPTile.nib b/PIA VPN dev.app/IPTile.nib new file mode 100644 index 000000000..1cb179329 Binary files /dev/null and b/PIA VPN dev.app/IPTile.nib differ diff --git a/PIA VPN dev.app/IPTileCollectionViewCell.nib/objects-12.3+.nib b/PIA VPN dev.app/IPTileCollectionViewCell.nib/objects-12.3+.nib new file mode 100644 index 000000000..49f60de48 Binary files /dev/null and b/PIA VPN dev.app/IPTileCollectionViewCell.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/IPTileCollectionViewCell.nib/runtime.nib b/PIA VPN dev.app/IPTileCollectionViewCell.nib/runtime.nib new file mode 100644 index 000000000..3c6c7edd6 Binary files /dev/null and b/PIA VPN dev.app/IPTileCollectionViewCell.nib/runtime.nib differ diff --git a/PIA VPN dev.app/Info.plist b/PIA VPN dev.app/Info.plist new file mode 100644 index 000000000..ba4f1234e Binary files /dev/null and b/PIA VPN dev.app/Info.plist differ diff --git a/PIA VPN dev.app/Launch Screen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib b/PIA VPN dev.app/Launch Screen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib new file mode 100644 index 000000000..8cdb60c63 Binary files /dev/null and b/PIA VPN dev.app/Launch Screen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib differ diff --git a/PIA VPN dev.app/Launch Screen.storyboardc/Info.plist b/PIA VPN dev.app/Launch Screen.storyboardc/Info.plist new file mode 100644 index 000000000..32288e88f Binary files /dev/null and b/PIA VPN dev.app/Launch Screen.storyboardc/Info.plist differ diff --git a/PIA VPN dev.app/Launch Screen.storyboardc/UIViewController-01J-lp-oVM.nib b/PIA VPN dev.app/Launch Screen.storyboardc/UIViewController-01J-lp-oVM.nib new file mode 100644 index 000000000..29c62978e Binary files /dev/null and b/PIA VPN dev.app/Launch Screen.storyboardc/UIViewController-01J-lp-oVM.nib differ diff --git a/PIA VPN dev.app/MessagesTile.nib b/PIA VPN dev.app/MessagesTile.nib new file mode 100644 index 000000000..0667b1f58 Binary files /dev/null and b/PIA VPN dev.app/MessagesTile.nib differ diff --git a/PIA VPN dev.app/MessagesTileCollectionViewCell.nib/objects-12.3+.nib b/PIA VPN dev.app/MessagesTileCollectionViewCell.nib/objects-12.3+.nib new file mode 100644 index 000000000..1c1990dfc Binary files /dev/null and b/PIA VPN dev.app/MessagesTileCollectionViewCell.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/MessagesTileCollectionViewCell.nib/runtime.nib b/PIA VPN dev.app/MessagesTileCollectionViewCell.nib/runtime.nib new file mode 100644 index 000000000..4b1a9d2e4 Binary files /dev/null and b/PIA VPN dev.app/MessagesTileCollectionViewCell.nib/runtime.nib differ diff --git a/PIA VPN dev.app/NetworkCollectionViewCell.nib/objects-12.3+.nib b/PIA VPN dev.app/NetworkCollectionViewCell.nib/objects-12.3+.nib new file mode 100644 index 000000000..58ea546b8 Binary files /dev/null and b/PIA VPN dev.app/NetworkCollectionViewCell.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/NetworkCollectionViewCell.nib/runtime.nib b/PIA VPN dev.app/NetworkCollectionViewCell.nib/runtime.nib new file mode 100644 index 000000000..1a5840f00 Binary files /dev/null and b/PIA VPN dev.app/NetworkCollectionViewCell.nib/runtime.nib differ diff --git a/PIA VPN dev.app/NetworkFooterCollectionViewCell.nib/objects-12.3+.nib b/PIA VPN dev.app/NetworkFooterCollectionViewCell.nib/objects-12.3+.nib new file mode 100644 index 000000000..cf418ac4a Binary files /dev/null and b/PIA VPN dev.app/NetworkFooterCollectionViewCell.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/NetworkFooterCollectionViewCell.nib/runtime.nib b/PIA VPN dev.app/NetworkFooterCollectionViewCell.nib/runtime.nib new file mode 100644 index 000000000..92dc3c478 Binary files /dev/null and b/PIA VPN dev.app/NetworkFooterCollectionViewCell.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIA VPN dev b/PIA VPN dev.app/PIA VPN dev new file mode 100755 index 000000000..9671c720f Binary files /dev/null and b/PIA VPN dev.app/PIA VPN dev differ diff --git a/PIA VPN dev.app/PIA-RSA-4096.pem b/PIA VPN dev.app/PIA-RSA-4096.pem new file mode 100644 index 000000000..82dec692d --- /dev/null +++ b/PIA VPN dev.app/PIA-RSA-4096.pem @@ -0,0 +1,43 @@ +-----BEGIN CERTIFICATE----- +MIIHqzCCBZOgAwIBAgIJAJ0u+vODZJntMA0GCSqGSIb3DQEBDQUAMIHoMQswCQYD +VQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNV +BAoTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIElu +dGVybmV0IEFjY2VzczEgMB4GA1UEAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3Mx +IDAeBgNVBCkTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkB +FiBzZWN1cmVAcHJpdmF0ZWludGVybmV0YWNjZXNzLmNvbTAeFw0xNDA0MTcxNzQw +MzNaFw0zNDA0MTIxNzQwMzNaMIHoMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex +EzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNVBAoTF1ByaXZhdGUgSW50ZXJuZXQg +QWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UE +AxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBCkTF1ByaXZhdGUgSW50 +ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkBFiBzZWN1cmVAcHJpdmF0ZWludGVy +bmV0YWNjZXNzLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALVk +hjumaqBbL8aSgj6xbX1QPTfTd1qHsAZd2B97m8Vw31c/2yQgZNf5qZY0+jOIHULN +De4R9TIvyBEbvnAg/OkPw8n/+ScgYOeH876VUXzjLDBnDb8DLr/+w9oVsuDeFJ9K +V2UFM1OYX0SnkHnrYAN2QLF98ESK4NCSU01h5zkcgmQ+qKSfA9Ny0/UpsKPBFqsQ +25NvjDWFhCpeqCHKUJ4Be27CDbSl7lAkBuHMPHJs8f8xPgAbHRXZOxVCpayZ2SND +fCwsnGWpWFoMGvdMbygngCn6jA/W1VSFOlRlfLuuGe7QFfDwA0jaLCxuWt/BgZyl +p7tAzYKR8lnWmtUCPm4+BtjyVDYtDCiGBD9Z4P13RFWvJHw5aapx/5W/CuvVyI7p +Kwvc2IT+KPxCUhH1XI8ca5RN3C9NoPJJf6qpg4g0rJH3aaWkoMRrYvQ+5PXXYUzj +tRHImghRGd/ydERYoAZXuGSbPkm9Y/p2X8unLcW+F0xpJD98+ZI+tzSsI99Zs5wi +jSUGYr9/j18KHFTMQ8n+1jauc5bCCegN27dPeKXNSZ5riXFL2XX6BkY68y58UaNz +meGMiUL9BOV1iV+PMb7B7PYs7oFLjAhh0EdyvfHkrh/ZV9BEhtFa7yXp8XR0J6vz +1YV9R6DYJmLjOEbhU8N0gc3tZm4Qz39lIIG6w3FDAgMBAAGjggFUMIIBUDAdBgNV +HQ4EFgQUrsRtyWJftjpdRM0+925Y6Cl08SUwggEfBgNVHSMEggEWMIIBEoAUrsRt +yWJftjpdRM0+925Y6Cl08SWhge6kgeswgegxCzAJBgNVBAYTAlVTMQswCQYDVQQI +EwJDQTETMBEGA1UEBxMKTG9zQW5nZWxlczEgMB4GA1UEChMXUHJpdmF0ZSBJbnRl +cm5ldCBBY2Nlc3MxIDAeBgNVBAsTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAw +HgYDVQQDExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UEKRMXUHJpdmF0 +ZSBJbnRlcm5ldCBBY2Nlc3MxLzAtBgkqhkiG9w0BCQEWIHNlY3VyZUBwcml2YXRl +aW50ZXJuZXRhY2Nlc3MuY29tggkAnS7684Nkme0wDAYDVR0TBAUwAwEB/zANBgkq +hkiG9w0BAQ0FAAOCAgEAJsfhsPk3r8kLXLxY+v+vHzbr4ufNtqnL9/1Uuf8NrsCt +pXAoyZ0YqfbkWx3NHTZ7OE9ZRhdMP/RqHQE1p4N4Sa1nZKhTKasV6KhHDqSCt/dv +Em89xWm2MVA7nyzQxVlHa9AkcBaemcXEiyT19XdpiXOP4Vhs+J1R5m8zQOxZlV1G +tF9vsXmJqWZpOVPmZ8f35BCsYPvv4yMewnrtAC8PFEK/bOPeYcKN50bol22QYaZu +LfpkHfNiFTnfMh8sl/ablPyNY7DUNiP5DRcMdIwmfGQxR5WEQoHL3yPJ42LkB5zs +6jIm26DGNXfwura/mi105+ENH1CaROtRYwkiHb08U6qLXXJz80mWJkT90nr8Asj3 +5xN2cUppg74nG3YVav/38P48T56hG1NHbYF5uOCske19F6wi9maUoto/3vEr0rnX +JUp2KODmKdvBI7co245lHBABWikk8VfejQSlCtDBXn644ZMtAdoxKNfR2WTFVEwJ +iyd1Fzx0yujuiXDROLhISLQDRjVVAvawrAtLZWYK31bY7KlezPlQnl/D9Asxe85l +8jO5+0LdJ6VyOs/Hd4w52alDW/MFySDZSfQHMTIc30hLBJ8OnCEIvluVQQ2UQvoW ++no177N9L2Y+M9TcTA62ZyMXShHQGeh20rb4kK8f+iFX8NxtdHVSkxMEFSfDDyQ= +-----END CERTIFICATE----- diff --git a/PIA VPN dev.app/PIACard.nib b/PIA VPN dev.app/PIACard.nib new file mode 100644 index 000000000..afe4734cf Binary files /dev/null and b/PIA VPN dev.app/PIACard.nib differ diff --git a/PIA VPN dev.app/PIAHeaderCollectionViewCell.nib/objects-12.3+.nib b/PIA VPN dev.app/PIAHeaderCollectionViewCell.nib/objects-12.3+.nib new file mode 100644 index 000000000..837cc9c96 Binary files /dev/null and b/PIA VPN dev.app/PIAHeaderCollectionViewCell.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIAHeaderCollectionViewCell.nib/runtime.nib b/PIA VPN dev.app/PIAHeaderCollectionViewCell.nib/runtime.nib new file mode 100644 index 000000000..1bb9c8176 Binary files /dev/null and b/PIA VPN dev.app/PIAHeaderCollectionViewCell.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Assets.car b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Assets.car new file mode 100644 index 000000000..25f8a3020 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Assets.car differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Info.plist b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Info.plist new file mode 100644 index 000000000..0896d6b6f Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Info.plist differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib new file mode 100644 index 000000000..782e63cc6 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib new file mode 100644 index 000000000..8232ab814 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib new file mode 100644 index 000000000..b7fc0e162 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib new file mode 100644 index 000000000..50dcfb5e7 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist new file mode 100644 index 000000000..fb8201739 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib new file mode 100644 index 000000000..c2c4aa7ad Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib new file mode 100644 index 000000000..d8a9d70a5 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib new file mode 100644 index 000000000..8ba9b88b5 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib new file mode 100644 index 000000000..64cc2e51b Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib new file mode 100644 index 000000000..17e8c708d Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib new file mode 100644 index 000000000..4a92bd1d6 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib new file mode 100644 index 000000000..5000c5c1e Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib new file mode 100644 index 000000000..bbd696c11 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib new file mode 100644 index 000000000..3ff6637ef Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib new file mode 100644 index 000000000..9087e9150 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..e7dd91219 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib new file mode 100644 index 000000000..e7dd91219 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist new file mode 100644 index 000000000..a6ffe0e5d Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib new file mode 100644 index 000000000..0328b5682 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib new file mode 100644 index 000000000..f984c8279 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..85c0f3668 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib new file mode 100644 index 000000000..85c0f3668 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..f871a40b0 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib new file mode 100644 index 000000000..f871a40b0 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..71abc0b03 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib new file mode 100644 index 000000000..71abc0b03 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..32df7a32a Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib new file mode 100644 index 000000000..32df7a32a Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..87eb0e1cc Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib new file mode 100644 index 000000000..87eb0e1cc Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib new file mode 100644 index 000000000..fba5e5b84 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib new file mode 100644 index 000000000..fba5e5b84 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib new file mode 100644 index 000000000..3a454f116 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib new file mode 100644 index 000000000..3a454f116 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib new file mode 100644 index 000000000..03629a06f Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib new file mode 100644 index 000000000..03629a06f Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib new file mode 100644 index 000000000..f2476efe7 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib new file mode 100644 index 000000000..f2476efe7 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib new file mode 100644 index 000000000..76a131359 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib new file mode 100644 index 000000000..76a131359 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib new file mode 100644 index 000000000..4cbd2e982 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib new file mode 100644 index 000000000..e16ab5e4f Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib new file mode 100644 index 000000000..3496a4bbf Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib new file mode 100644 index 000000000..3496a4bbf Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib new file mode 100644 index 000000000..fcfccf837 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib new file mode 100644 index 000000000..fcfccf837 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory new file mode 100644 index 000000000..37d89a56f Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements new file mode 100644 index 000000000..dbf9d6144 Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 new file mode 100644 index 000000000..b99f9a94a Binary files /dev/null and b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 differ diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources new file mode 100644 index 000000000..93086328a --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources @@ -0,0 +1,1991 @@ + + + + + files + + Assets.car + + 8h6Hyf4U9/+JlpRmAN3vBaPEjrw= + + Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + dytHgVNc10hWhKQW+WIDasbWdTU= + + Signup.storyboardc/ConfirmVPNPlanViewController.nib + + OVb1ASokoqm9FsqgYqS4ykOLvTk= + + Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + qEnPzvZ7YJ2malb9v8b6uU1qRtI= + + Signup.storyboardc/GDPRViewController.nib + + BnH89TJFPy09hwlepgmy1qX8w5I= + + Signup.storyboardc/Info.plist + + tvSnglTgEmfEVDs4Pqzq89zCWdk= + + Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + htQTSxHbapTjr/KU4MZ+BReh+fg= + + Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + CJa19sBIiRCsSpkmvlAK9WVgIUc= + + Signup.storyboardc/ShareDataInformationViewController.nib + + DClrKMNBhP7R57XPbVZNLZEkhHY= + + Signup.storyboardc/SignupSuccessViewController.nib + + RII82MT1u8xiVhoF6z8GAPWRauw= + + Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + YpRMevT/Hk92B7qxIoBZNubmhVo= + + Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + bJ8pWQoqUwPJh2R449Z5iB80fgw= + + Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + XIT4vTE0sbcaxPw4Ukcc10AudMU= + + Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + 8QYAr5CSJVq9J2M/WNeKrHxyH4k= + + Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + /KugdZ7rq/us89d7xS8Y4W80uoE= + + Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + lAQN56rjGXobwkMhOfbs34FT+S8= + + Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + Welcome.storyboardc/Info.plist + + /pYtZWavELI0+6nEkTUa0WNFSew= + + Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + QLgeyu0ZVc/lDmyITQfrBSRT2Hk= + + Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + gA8eOIpUQd1BEBgO/w9hDFS+JxU= + + Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + Welcome.storyboardc/LoginViewController.nib/runtime.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + GzhYGB3AyZ0wytBn61POuwdsJ7E= + + Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + sQtUseVfpjT4CFtCBgvBwDjWfQA= + + Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + ar.lproj/Signup.strings + + hash + + KDACaW+muq3Q7S2KFi/tSoBrOA0= + + optional + + + ar.lproj/UI.strings + + hash + + q69blyRGQI14B9CBKT9Rsw4dq0k= + + optional + + + ar.lproj/Welcome.strings + + hash + + BkACZwewt5pWHuYeiW8u/ttymCg= + + optional + + + da.lproj/Signup.strings + + hash + + ImqHeuQyhd4vbb7tX6gDpc0Uws4= + + optional + + + da.lproj/UI.strings + + hash + + JEB6TYMiWHIJ3Fwzv9hwS3X5B9c= + + optional + + + da.lproj/Welcome.strings + + hash + + 0U+OaxIpF3m54GcZw6Rj0FT9IQU= + + optional + + + de.lproj/Signup.strings + + hash + + ULQLCKJ1Tkx5LYNqw+wZAPpz+fc= + + optional + + + de.lproj/UI.strings + + hash + + 1964G9tW/vLUljfWDybLqmj8ovo= + + optional + + + de.lproj/Welcome.strings + + hash + + j/jLkt7lT5WaqzpSmS2HeZ2YT7g= + + optional + + + en.lproj/Signup.strings + + hash + + EZ9QZ7PSibfcWSeEETK4rR/PkKE= + + optional + + + en.lproj/UI.strings + + hash + + 8v4J37YS+jZq3LBvpRfFdfrmOjo= + + optional + + + en.lproj/Welcome.strings + + hash + + BwdYyKtC03avQBNFX31HfqSElzI= + + optional + + + es-MX.lproj/Signup.strings + + hash + + /cuvVUGtYOlubi9pgRpN8GF6eaQ= + + optional + + + es-MX.lproj/UI.strings + + hash + + iiP5bcCQB5ClycQCkVGeHIMUAks= + + optional + + + es-MX.lproj/Welcome.strings + + hash + + lx4/QzIqPJcVTvU4PUA9DuA+iR0= + + optional + + + fr.lproj/Signup.strings + + hash + + vRPh7xNvA8CBlDbvqId98Ppaol4= + + optional + + + fr.lproj/UI.strings + + hash + + IbgvE2UN4PxyRd+exu9NKENUaI0= + + optional + + + fr.lproj/Welcome.strings + + hash + + KoygslQ7+C06O61A0YHLMJPIhd8= + + optional + + + it.lproj/Signup.strings + + hash + + Ed4oYGhilkGVvO6AshjBjzdE+7w= + + optional + + + it.lproj/UI.strings + + hash + + Y50/iDsqGezjtBuqSlPo8jymMAc= + + optional + + + it.lproj/Welcome.strings + + hash + + 8OHVfUCzQp3y5Avt0qvL0KEijp8= + + optional + + + ja.lproj/Signup.strings + + hash + + nNEDjklKvB3EYDy3z/dKvk0Y3Sc= + + optional + + + ja.lproj/UI.strings + + hash + + +2YIistydmlPjDts2u1ROqKtWqI= + + optional + + + ja.lproj/Welcome.strings + + hash + + RbM1jidNxxT0GrCW5Bp4AJ2C10U= + + optional + + + ko.lproj/Signup.strings + + hash + + v+qEVshU1lPCEIX6p/5VNVvHCsE= + + optional + + + ko.lproj/UI.strings + + hash + + XSewfIvou+2vfPzfd4L1JobLejU= + + optional + + + ko.lproj/Welcome.strings + + hash + + j/ZhhE8EhAk/Lumf0d8hAl0mnM0= + + optional + + + nb.lproj/Signup.strings + + hash + + KhJ/QqRfNp4OZfzpif4GtcBF8bI= + + optional + + + nb.lproj/UI.strings + + hash + + xDMWYimFFDfSHhe2YZpdtrl2g8k= + + optional + + + nb.lproj/Welcome.strings + + hash + + uwWBmqf4ftnCEhc6CREp8ByROW4= + + optional + + + nl.lproj/Signup.strings + + hash + + NyXHmGW4hA/Eauh4ij9O5S5WhTA= + + optional + + + nl.lproj/UI.strings + + hash + + YZpZdbu3r3xtH/jvKMalDSa3lOc= + + optional + + + nl.lproj/Welcome.strings + + hash + + yqehLrthKrrux3wlT4BXD2o86VM= + + optional + + + pl.lproj/Signup.strings + + hash + + 6OMfwEOtzCuZV03uZytGep2fVcM= + + optional + + + pl.lproj/UI.strings + + hash + + K6FfGb4sRyZ+8fUCnq80qKRGipc= + + optional + + + pl.lproj/Welcome.strings + + hash + + jdPps229/rIXz+/ddHNG9FuKBhQ= + + optional + + + pt-BR.lproj/Signup.strings + + hash + + fbM6TjAWhkqwQRqlFgXqxwrx+8k= + + optional + + + pt-BR.lproj/UI.strings + + hash + + 5JKfMEQAm3AUcBKlsob0yfJRkQk= + + optional + + + pt-BR.lproj/Welcome.strings + + hash + + 01ji1w1oANjR7h5TRr6cBlyaRGo= + + optional + + + ru.lproj/Signup.strings + + hash + + ZPLrICgFyE180EQFQQsAPW2T0LY= + + optional + + + ru.lproj/UI.strings + + hash + + Ke55XO9cpqEQhKUHTr3HEvi0aUM= + + optional + + + ru.lproj/Welcome.strings + + hash + + rfmjmvw733cPOhxZ0RizNQfXkSE= + + optional + + + th.lproj/Signup.strings + + hash + + awJpWTrrqH31sd1t1ndiEy4cN/A= + + optional + + + th.lproj/UI.strings + + hash + + QMaBIt1A8kjNOstov8L0lchT5Ec= + + optional + + + th.lproj/Welcome.strings + + hash + + 5J5E4i04UUqsWy3SQZN1zcKIZaQ= + + optional + + + tr.lproj/Signup.strings + + hash + + 55QLf0o5XG8IWfXbQ6KvFWToA+4= + + optional + + + tr.lproj/UI.strings + + hash + + hfdFuAQLTfdHleeMkh4YCtlcNBY= + + optional + + + tr.lproj/Welcome.strings + + hash + + R49azaTbZXexzZ4fO2KAO8IQIW4= + + optional + + + zh-Hans.lproj/Signup.strings + + hash + + B3OiNtJOoqFlNs77EeQh3/YlwiU= + + optional + + + zh-Hans.lproj/UI.strings + + hash + + athEoNydnFVAkLxqKvlUTv5EfZg= + + optional + + + zh-Hans.lproj/Welcome.strings + + hash + + 6aHDe64C6X+IcTDg3C39b+SM9Ls= + + optional + + + zh-Hant.lproj/Signup.strings + + hash + + InQh2yXFC6brp+xf2gtnVDZtsuY= + + optional + + + zh-Hant.lproj/UI.strings + + hash + + 7NuRLJG/PUbRlsl/6dZTfboVNfQ= + + optional + + + zh-Hant.lproj/Welcome.strings + + hash + + hBHKqa7nicnE6j15W8iBNQQdsws= + + optional + + + + files2 + + Assets.car + + hash + + 8h6Hyf4U9/+JlpRmAN3vBaPEjrw= + + hash2 + + z2oHVz8/itmR3oqHY51lv6NTMX9epuIIiBsUG+B3f3M= + + + Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + hash + + dytHgVNc10hWhKQW+WIDasbWdTU= + + hash2 + + EHhu+ZyC8bLdGTREBf6He41YqGou0HpQDQ4u1t+B67c= + + + Signup.storyboardc/ConfirmVPNPlanViewController.nib + + hash + + OVb1ASokoqm9FsqgYqS4ykOLvTk= + + hash2 + + Rr/ex+JnT00WjY8BTVZWRNqz/GfU4jaR3v03FmrukIA= + + + Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + hash + + qEnPzvZ7YJ2malb9v8b6uU1qRtI= + + hash2 + + fkNfOkKA9R7NGpPPFiVhuYQ2+AdSVeR9osgZyyAms58= + + + Signup.storyboardc/GDPRViewController.nib + + hash + + BnH89TJFPy09hwlepgmy1qX8w5I= + + hash2 + + hDcEgabY8XWIV+bMHjY9T2LEXhXGYAjSsL1LyHygu1A= + + + Signup.storyboardc/Info.plist + + hash + + tvSnglTgEmfEVDs4Pqzq89zCWdk= + + hash2 + + +ULlbQDKRqZAgLPRQ4aWV271svAlSIpTvPj8fAxklSA= + + + Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + hash + + htQTSxHbapTjr/KU4MZ+BReh+fg= + + hash2 + + vqbeJEql0Jgydj1T24xy6xJbrXkBGPmYusMqnTCSGcM= + + + Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + hash + + CJa19sBIiRCsSpkmvlAK9WVgIUc= + + hash2 + + 28vreA7cNtWCBn0Hh2oGxsleKe0mqFxApasYvvlSWTo= + + + Signup.storyboardc/ShareDataInformationViewController.nib + + hash + + DClrKMNBhP7R57XPbVZNLZEkhHY= + + hash2 + + FLZ/2WLEaK53aWKIJqX9T7ltNA15ERKTr7oZHeg14vU= + + + Signup.storyboardc/SignupSuccessViewController.nib + + hash + + RII82MT1u8xiVhoF6z8GAPWRauw= + + hash2 + + 7XhIk/s4X/sIr5xEWP1PVGI7EV+vDS5HktrZ/OskXUk= + + + Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + hash + + YpRMevT/Hk92B7qxIoBZNubmhVo= + + hash2 + + N91d6/YhJJHCGX6EQSKWaoeSLBzL4sitnyKgo7IerzU= + + + Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + hash + + bJ8pWQoqUwPJh2R449Z5iB80fgw= + + hash2 + + LmfITndcyawR5vC3q1+ZA3Tmezvc/H/UOm9eNi8rkXQ= + + + Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + hash + + XIT4vTE0sbcaxPw4Ukcc10AudMU= + + hash2 + + cxj3iSMzDtgAEjJCn2Kh4wOxq643eP+NVKmuyRy4ScE= + + + Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + hash + + 8QYAr5CSJVq9J2M/WNeKrHxyH4k= + + hash2 + + +pb1yeNeVETkzR3D7bHHd7b/7ckHANG2FYkou4fexeA= + + + Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + hash + + /KugdZ7rq/us89d7xS8Y4W80uoE= + + hash2 + + LcuEIHcg/ABNnzlBcFJUh1QnZG6OeeODUinCRME6gVM= + + + Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + hash + + lAQN56rjGXobwkMhOfbs34FT+S8= + + hash2 + + 2sqAv9sKlmNLJyLvObb9ssgf6q3St0BYeyc41iKo10w= + + + Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + hash + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + hash + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + Welcome.storyboardc/Info.plist + + hash + + /pYtZWavELI0+6nEkTUa0WNFSew= + + hash2 + + Y3Hpojl68zniB+aUL9PZXEVKtWuzsnlbS5/xAZKFhAo= + + + Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + hash + + QLgeyu0ZVc/lDmyITQfrBSRT2Hk= + + hash2 + + rvJVcZPH3KzWKHiwzq/TcFc5ZloThq9gqavWaC6uX0s= + + + Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + hash + + gA8eOIpUQd1BEBgO/w9hDFS+JxU= + + hash2 + + 7V3P3q8VYMDAWwvrjqD85I4/kwFbGlegJ76JkMn8sDc= + + + Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + hash + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + Welcome.storyboardc/LoginViewController.nib/runtime.nib + + hash + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + hash + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + hash + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + hash + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + hash + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + hash + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + hash + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + hash + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + hash + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + hash + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + hash + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + hash + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + hash + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + hash + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + hash + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + hash + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + hash + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + hash + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + hash + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + hash + + GzhYGB3AyZ0wytBn61POuwdsJ7E= + + hash2 + + ZXVhR7A3IzlBTiK3AT8wLUDQeJhM59ywT6AJJWSHNuE= + + + Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + hash + + sQtUseVfpjT4CFtCBgvBwDjWfQA= + + hash2 + + gE07Q/56h7roPAuaRZhMhxJ+wNhM0gvRduQ2/Him9z8= + + + Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + hash + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + hash + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + hash + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + hash + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + ar.lproj/Signup.strings + + hash + + KDACaW+muq3Q7S2KFi/tSoBrOA0= + + hash2 + + /PdaPdFVdwwWy0WMwLSdWCQv9CkI1tpm2JyG/6Tmn9M= + + optional + + + ar.lproj/UI.strings + + hash + + q69blyRGQI14B9CBKT9Rsw4dq0k= + + hash2 + + YhKnZ6a5ITfwAgnv/6Cd1x+TPQ067/rO+K+rWNEzD6w= + + optional + + + ar.lproj/Welcome.strings + + hash + + BkACZwewt5pWHuYeiW8u/ttymCg= + + hash2 + + S1/lODt2iX9EyVMvBt0dsAV6rYE8BdXAlCaTa1+HTsw= + + optional + + + da.lproj/Signup.strings + + hash + + ImqHeuQyhd4vbb7tX6gDpc0Uws4= + + hash2 + + +bSgSn+Mt62wraeSALDwHwkp4db5Q4ig2thAObbQPnc= + + optional + + + da.lproj/UI.strings + + hash + + JEB6TYMiWHIJ3Fwzv9hwS3X5B9c= + + hash2 + + doJ3NS9+wFy5hCKe75hwGTA8tafBSrCQJnnrwcghQQs= + + optional + + + da.lproj/Welcome.strings + + hash + + 0U+OaxIpF3m54GcZw6Rj0FT9IQU= + + hash2 + + udZzYVGokipS7z20EPQUqoeoTxmet5LGclYicXo/Qzc= + + optional + + + de.lproj/Signup.strings + + hash + + ULQLCKJ1Tkx5LYNqw+wZAPpz+fc= + + hash2 + + 3qf/FrW+/u8t/lO9wA/+NtfCBtCJ1WguXGz2uvwUoc0= + + optional + + + de.lproj/UI.strings + + hash + + 1964G9tW/vLUljfWDybLqmj8ovo= + + hash2 + + OqXvZaKPjVRbECIamvYeVtO1k5SXy41xBrfoDBODJzU= + + optional + + + de.lproj/Welcome.strings + + hash + + j/jLkt7lT5WaqzpSmS2HeZ2YT7g= + + hash2 + + /RCU9b12hOYxRv0uKqNRMyGNoOs2qGmTkLw0Js7xFcQ= + + optional + + + en.lproj/Signup.strings + + hash + + EZ9QZ7PSibfcWSeEETK4rR/PkKE= + + hash2 + + eTcLQYTr4H9oZFv0rxYaq3gQ+WhpLjFnSyzwaOIiehc= + + optional + + + en.lproj/UI.strings + + hash + + 8v4J37YS+jZq3LBvpRfFdfrmOjo= + + hash2 + + 2LmfTdHJMvlivEZbaU9xSJAAnvlpBpvBa+WumfJ+Zbs= + + optional + + + en.lproj/Welcome.strings + + hash + + BwdYyKtC03avQBNFX31HfqSElzI= + + hash2 + + oAZWhsRhLpQkW9ZhuKf4MOb41w5Y8MZPZx3S0NMM5tk= + + optional + + + es-MX.lproj/Signup.strings + + hash + + /cuvVUGtYOlubi9pgRpN8GF6eaQ= + + hash2 + + nI1MegvByIjofRyKN8F43cuCTWoXr5uIExtoQ3BK6NM= + + optional + + + es-MX.lproj/UI.strings + + hash + + iiP5bcCQB5ClycQCkVGeHIMUAks= + + hash2 + + a8Vp2K22QfOvNgn1DCjRhoTHkZVdwywOmftje9rC42Y= + + optional + + + es-MX.lproj/Welcome.strings + + hash + + lx4/QzIqPJcVTvU4PUA9DuA+iR0= + + hash2 + + mxe8YvU0Z6ToCEE2d86cOJNrmOVz8cRCJpBzDQWLVWc= + + optional + + + fr.lproj/Signup.strings + + hash + + vRPh7xNvA8CBlDbvqId98Ppaol4= + + hash2 + + QqrxBLWpNYv5rrqBFN8BLC6LNXUmQVa74Gl+0ksKBZU= + + optional + + + fr.lproj/UI.strings + + hash + + IbgvE2UN4PxyRd+exu9NKENUaI0= + + hash2 + + Pv8eZpPXvR5mqm53bwD8agrzEaWy3xj6YdWgIOflm+M= + + optional + + + fr.lproj/Welcome.strings + + hash + + KoygslQ7+C06O61A0YHLMJPIhd8= + + hash2 + + xyVMkl7jhNBZ/vN0ZFmM2FlY8ovTdbitINQqEgRyqks= + + optional + + + it.lproj/Signup.strings + + hash + + Ed4oYGhilkGVvO6AshjBjzdE+7w= + + hash2 + + VlWjS5dJ4UNfaNhHqlxeKfkECiko5YzTss4+zOmzYJ4= + + optional + + + it.lproj/UI.strings + + hash + + Y50/iDsqGezjtBuqSlPo8jymMAc= + + hash2 + + y2JDFhY4F9hvHbr4F4pF6PrFuy4JUyVFpMw8BcbSBY4= + + optional + + + it.lproj/Welcome.strings + + hash + + 8OHVfUCzQp3y5Avt0qvL0KEijp8= + + hash2 + + lu+ZwHtxRo9m+9fmCbojh8YbdagKuR6eYwXH/O4QNHo= + + optional + + + ja.lproj/Signup.strings + + hash + + nNEDjklKvB3EYDy3z/dKvk0Y3Sc= + + hash2 + + bDq3nM4T1ut8Ts8+QYkxdWNGRu+//zSf189mi3aRlQ8= + + optional + + + ja.lproj/UI.strings + + hash + + +2YIistydmlPjDts2u1ROqKtWqI= + + hash2 + + YaeZ3JgOA+qIusYRqxxG6pwBkrFim1rw7qTyLnl060I= + + optional + + + ja.lproj/Welcome.strings + + hash + + RbM1jidNxxT0GrCW5Bp4AJ2C10U= + + hash2 + + Xq2cl5IrUxxaYjKRRxrCcWp8u2KzQtjBAPMG2ywwICA= + + optional + + + ko.lproj/Signup.strings + + hash + + v+qEVshU1lPCEIX6p/5VNVvHCsE= + + hash2 + + tGa6ibOVYp6N7/L++jdOleoT9KE1QQ1PK1rhzpVOKDQ= + + optional + + + ko.lproj/UI.strings + + hash + + XSewfIvou+2vfPzfd4L1JobLejU= + + hash2 + + QIUwyVItXRoQKXGmgHFFotXmiOSE9JxkZlaoE2IHX+8= + + optional + + + ko.lproj/Welcome.strings + + hash + + j/ZhhE8EhAk/Lumf0d8hAl0mnM0= + + hash2 + + weQQxyn+b2SpWKeGAvJqE/ii7MCRaDRxNADg8r9TvYI= + + optional + + + nb.lproj/Signup.strings + + hash + + KhJ/QqRfNp4OZfzpif4GtcBF8bI= + + hash2 + + RnLEv00iw5lOIGL/XJzJU1ShBwn9hBnC4hNhikuyhA4= + + optional + + + nb.lproj/UI.strings + + hash + + xDMWYimFFDfSHhe2YZpdtrl2g8k= + + hash2 + + CbdEeBsje8P4+h3x6IQ57ZROUQ898FBunnH3ZY69DnQ= + + optional + + + nb.lproj/Welcome.strings + + hash + + uwWBmqf4ftnCEhc6CREp8ByROW4= + + hash2 + + 3l4+0NbmewoK9l0/qdkIGPcqqrLIRM5eOrwPHGkUEy0= + + optional + + + nl.lproj/Signup.strings + + hash + + NyXHmGW4hA/Eauh4ij9O5S5WhTA= + + hash2 + + VfV2uL8OKA5ZiR3yiHFT65ZEHaCbkn35Yo+ur18Bqxw= + + optional + + + nl.lproj/UI.strings + + hash + + YZpZdbu3r3xtH/jvKMalDSa3lOc= + + hash2 + + 69DUk8Zeh5SReiVA+Wk9iHozzU98pp8V8uFeG+EA+A0= + + optional + + + nl.lproj/Welcome.strings + + hash + + yqehLrthKrrux3wlT4BXD2o86VM= + + hash2 + + LHqIVFxiS7xOGRDl+Mc94nzpdWHZpV7V+YNrcO3F6rw= + + optional + + + pl.lproj/Signup.strings + + hash + + 6OMfwEOtzCuZV03uZytGep2fVcM= + + hash2 + + me1r0CSvQxGrjhri1zbZY30vF6XWxdoV5q/XNHlGVhs= + + optional + + + pl.lproj/UI.strings + + hash + + K6FfGb4sRyZ+8fUCnq80qKRGipc= + + hash2 + + frs+aVxqmI1A7qNQ3lTqmaN+e68SScT1D6TutOPSHFs= + + optional + + + pl.lproj/Welcome.strings + + hash + + jdPps229/rIXz+/ddHNG9FuKBhQ= + + hash2 + + xQJW7uzg6y9kJf1gLZnCM9oO+0wQ84AayU+o+TV5Y2I= + + optional + + + pt-BR.lproj/Signup.strings + + hash + + fbM6TjAWhkqwQRqlFgXqxwrx+8k= + + hash2 + + MnV7VMLXWFm/KNE5a8UHkxR04f0OznpqoK1+9hyw8zY= + + optional + + + pt-BR.lproj/UI.strings + + hash + + 5JKfMEQAm3AUcBKlsob0yfJRkQk= + + hash2 + + DxvjdPIJCkbOywZjS5+ayQkGKWHlrGcquTxizAdezyg= + + optional + + + pt-BR.lproj/Welcome.strings + + hash + + 01ji1w1oANjR7h5TRr6cBlyaRGo= + + hash2 + + LDC5bZkG2h8AgTQLoL1yMj6JJA/ir2Qs9YoX0A27QLc= + + optional + + + ru.lproj/Signup.strings + + hash + + ZPLrICgFyE180EQFQQsAPW2T0LY= + + hash2 + + WWOM/zJIvlgQASAWOk/VrhJ76xkmJSNIM383qyAebmY= + + optional + + + ru.lproj/UI.strings + + hash + + Ke55XO9cpqEQhKUHTr3HEvi0aUM= + + hash2 + + oSkpUWDyzNoWL+/tE+JqlzA0l5XGRGrg0sa5Gvpc4eA= + + optional + + + ru.lproj/Welcome.strings + + hash + + rfmjmvw733cPOhxZ0RizNQfXkSE= + + hash2 + + NeG7RvpFs7aBDoclE4CeSnfGf9AS7tGvjGr/m1zT3eY= + + optional + + + th.lproj/Signup.strings + + hash + + awJpWTrrqH31sd1t1ndiEy4cN/A= + + hash2 + + buuAYnSRdzIW7wnFAfyIoc2xNnPeH6VmMpaTl1UnDcI= + + optional + + + th.lproj/UI.strings + + hash + + QMaBIt1A8kjNOstov8L0lchT5Ec= + + hash2 + + 86j7ej1K8vjK2Wc+4VvI8COo0F5VNrFgab6jFb52UQM= + + optional + + + th.lproj/Welcome.strings + + hash + + 5J5E4i04UUqsWy3SQZN1zcKIZaQ= + + hash2 + + CWB5kJ7tdPh65LpMEk7ON91tZXYPjCLHG3+KYt/Wor8= + + optional + + + tr.lproj/Signup.strings + + hash + + 55QLf0o5XG8IWfXbQ6KvFWToA+4= + + hash2 + + J7rTcADNQWVMdE7ToyJl5ztWFP7nS0LpgiIcVb4D/H8= + + optional + + + tr.lproj/UI.strings + + hash + + hfdFuAQLTfdHleeMkh4YCtlcNBY= + + hash2 + + mn9KO/anRw5JkawqXZT06MvC8pSCiTjPxNb+c3RrZ1I= + + optional + + + tr.lproj/Welcome.strings + + hash + + R49azaTbZXexzZ4fO2KAO8IQIW4= + + hash2 + + 3U8T+edoinqQskEd4Y8vg0sVEFsjDRp4YCrhcTIq0Nw= + + optional + + + zh-Hans.lproj/Signup.strings + + hash + + B3OiNtJOoqFlNs77EeQh3/YlwiU= + + hash2 + + 92+yGo0u+BgXiVmoYH9vE1wxCXffUp20Eb5V8JkLJDU= + + optional + + + zh-Hans.lproj/UI.strings + + hash + + athEoNydnFVAkLxqKvlUTv5EfZg= + + hash2 + + iDsYoUTxx8POedODQmaipEBJukmHm0klpri/JSYxzCg= + + optional + + + zh-Hans.lproj/Welcome.strings + + hash + + 6aHDe64C6X+IcTDg3C39b+SM9Ls= + + hash2 + + NtHmRVKzAicr7H8AVAqK8Bni236Z2cMnLjdcG/U7T6M= + + optional + + + zh-Hant.lproj/Signup.strings + + hash + + InQh2yXFC6brp+xf2gtnVDZtsuY= + + hash2 + + ajON8rkioyflp0u9oIDFniyq4zryBG0tC/51c7OOzbY= + + optional + + + zh-Hant.lproj/UI.strings + + hash + + 7NuRLJG/PUbRlsl/6dZTfboVNfQ= + + hash2 + + IvX18xiU0gageVb9uJLXqnoj5htrqNqSWI1LCqnTWY0= + + optional + + + zh-Hant.lproj/Welcome.strings + + hash + + hBHKqa7nicnE6j15W8iBNQQdsws= + + hash2 + + E7PBBBbQdDJESlMtJW1vcQ17At7XbJBTHK0Mbm0eyU0= + + optional + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature new file mode 100644 index 000000000..e69de29bb diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings new file mode 100644 index 000000000..ce7d9f39d --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "تأكيد التسجيل"; +"in_progress.message" = "جارٍ تأكيد عملية الشراء مع نظامنا. يمكن أن يستغرق ذلك لحظة لذلك انتظر قليلًا."; +"in_progress.redeem.message" = "جارٍ تأكيد رمز بطاقتك مع نظامنا. قد يستغرق ذلك بضع لحظات، انتظر قليلًا."; + +"success.title" = "تم الشراء"; +"success.message_format" = "شضكراً على اشتراكك معنا. لقد أرسلنا اسم المستخدم وكلمة المرور الخاصين بك إلى بريدك الإلكتروني %@"; +"success.redeem.title" = "تم استبدال البطاقة بنجاح"; +"success.redeem.message" = "ستصلك رسالة عبر البريد الإلكتروني تتضمن اسم المستخدم وكلمة المرور.\n\nتفاصيل تسجيل الدخول"; +"success.username.caption" = "اسم المستخدم"; +"success.password.caption" = "كلمة المرور"; +"success.submit" = "كيف تبدأ"; + +"failure.vc_title" = "فشل تسجيل الآن"; +"failure.title" = "فشل إنشاء الحساب"; +"failure.message" = "يتعذر علينا إنشاء حساب في الوقت الحالي. يرجى إعادة المحاولة لاحقًا. \n\nعند إعادة فتح التطبيق سيتم إعادة محاولة إنشاء حساب."; +"failure.purchase.sandbox.message" = "اشتراك الصندوق المحدد غير متاح في الإنتاج."; +"failure.redeem.invalid.title" = "رمز بطاقة غير صالح"; +"failure.redeem.invalid.message" = "يبدو أنك أدخلت رمز بطاقة غير صالح. يرجى إعادة المحاولة."; +"failure.redeem.claimed.title" = "تم استخدام هذه البطاقة بالفعل"; +"failure.redeem.claimed.message" = "يبدو أن هذه البطاقة استُخدمت في حساب آخر. حاول إدخال رمز جديد."; +"failure.submit" = "عودة"; + +"unreachable.vc_title" = "خطأ"; +"unreachable.title" = "أوبس!"; +"unreachable.message" = "لم يتم العثور على اتصال بالإنترنت. يرجى التأكد من اتصالك بالإنترنت وضغط زر إعادة المحاولة أدناه.\n\nيمكنك العودة إلى التطبيق في وقت لاحق لإنهاء العملية."; +"unreachable.submit" = "أعد المحاولة"; + +"purchase.uncredited.alert.message" = "لديك معاملات غير معتمدة. هل تريد استعادة تفاصيل حسابك؟"; +"purchase.uncredited.alert.button.cancel" = "إلغاء"; +"purchase.uncredited.alert.button.recover" = "استعادة الحساب"; + +"purchase.trials.intro" = "ابدأ تجربتك المجانية لمدة 7 ايام"; +"purchase.trials.price.after" = "ثم %@"; +"purchase.trials.money.back" = "ضمان استرداد المال لمدة 30 أيام"; +"purchase.trials.1year.protection" = "1 سنة من الخصوصية وحماية الهوية"; +"purchase.trials.anonymous" = "تصفح مجهول الهوية وإخفاء عنوان IP."; +"purchase.trials.devices" = "يدعم 10 أجهزة في المرة الواحدة"; +"purchase.trials.devices.description" = "احمي نفسك على ما يصل إلى 10 أجهزة في وقت واحد."; +"purchase.trials.region" = "اتصل بأي منطقة بسهولة"; +"purchase.trials.servers" = "أكثر من 3300 خادم في 32 دولة"; +"purchase.trials.start" = "ابدأ الاشتراك"; +"purchase.trials.all.plans" = "مشاهدة جميع الخطط المتاحة"; + +"purchase.subscribe.now" = "اشتراك الآن"; + +// WALKTHROUGH + +"walkthrough.action.next" = "التالي"; +"walkthrough.action.done" = "تم"; +"walkthrough.action.skip" = "تخطي"; + +"walkthrough.page.1.title" = "يدعم 10 أجهزة في المرة الواحدة"; +"walkthrough.page.1.description" = "احمي نفسك على ما يصل إلى 10 أجهزة في وقت واحد."; +"walkthrough.page.2.title" = "اتصل بأي منطقة بسهولة"; +"walkthrough.page.2.description" = "مع خوادم في جميع أنحاء العالم، أنت دائما تحت الحماية."; +"walkthrough.page.3.title" = "احمي نفسك من الإعلانات"; +"walkthrough.page.3.description" = "تمكين ميزة حظر المحتوى يمنع الإعلانات من الظهور في Safari."; + +"share.data.buttons.accept" = "قبول"; +"share.data.buttons.noThanks" = "لا، شكرًا"; +"share.data.buttons.readMore" = "قراءة المزيد"; +"share.data.text.title" = "يرجى مساعدتنا في تحسين خدمتنا"; +"share.data.text.description" = "لمساعدتنا في ضمان أداء اتصال خدمتنا، يمكنك مشاركة إحصائيات اتصالك معنا دون الكشف عن هويتك. لا تتضمن هذه التقارير أي معلومات محددة للشخصية."; +"share.data.text.footer" = "يمكنك دائمًا التحكم في ذلك من إعداداتك"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings new file mode 100644 index 000000000..d93d9b375 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "الإصدار %@ (%@)"; +"global.close" = "إغلاق"; +"global.ok" = "موافق"; +"global.cancel" = "إلغاء"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings new file mode 100644 index 000000000..75d5562b2 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "سجل الدخول إلى حسابك"; +"login.username.placeholder" = "اسم المستخدم (p1234567)"; +"login.password.placeholder" = "كلمة المرور"; +"login.submit" = "تسجيل الدخول"; +"login.restore.button" = "لم تحصل على تفاصيل الحساب؟"; +"login.error.title" = "تسجيل الدخول"; +"login.error.validation" = "يجب إدخال اسم المستخدم وكلمة المرور"; +"login.error.unauthorized" = "اسم المستخدم أو كلمة المرور غير صحيحة."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "تسجيل الدخول باستخدام إيصال الشراء"; +"login.magic.link.title" = "تسجيل الدخول باستخدام رابط البريد الإلكتروني السحري"; +"login.magic.link.response" = "يرجى إلقاء نظرة على بريدك الإلكتروني للحصول على رابط تسجيل الدخول."; +"login.magic.link.send" = "إرسال الرابط"; +"login.magic.link.invalid.email" = "البريد الإلكتروني غير صحيح. يرجى إعادة المحاولة."; + +"purchase.title" = "حدد خطة VPN"; +"purchase.subtitle" = "ضمان استرداد المال لمدة 7 أيام"; +"purchase.email.placeholder" = "البريد الإلكتروني"; +"purchase.continue" = "متابعة"; +"purchase.login.footer" = "لديك حساب بالفعل؟"; +"purchase.login.button" = "تسجيل الدخول"; +"purchase.error.title" = "شراء"; +"purchase.error.validation" = "يجب إدخال عنوان بريد إلكتروني."; +"purchase.error.connectivity.title" = "فشل الاتصال"; +"purchase.error.connectivity.description" = "لم نتمكن من الوصول إلى منفذ الإنترنت الخاص. ربما بسبب اتصال ضعيف بالإنترنت أو خدماتنا موقوفة في بلدك."; +"purchase.confirm.form.email" = "يرجى إدخال بريدك الإلكتروني"; +"purchase.confirm.plan" = "أنت تشتري الآن خطة %@"; +"purchase.email.why" = "نحتاج إلى بريدك الإلكتروني لإرسال اسم المستخدم وكلمة المرور."; +"purchase.submit" = "إرسال"; +"purchase.or" = "أو"; + +"upgrade.header" = "مرحبًا بعودتك!"; +"upgrade.title" = "لاستخدام Private Internet Access، تحتاج إلى تجديد اشتراكك."; +"upgrade.renew.now" = "تجديد الآن"; + + + +"redeem.title" = "استلم محتويات بطاقة هدية"; +"redeem.subtitle" = "أدخل بريدك الإلكتروني ورمز بطاقة الهدية أو بطاقة التجربة المكون من %lu خانات."; +"redeem.email.placeholder" = "البريد الإلكتروني"; +"redeem.submit" = "إرسال"; +"redeem.error.title" = "استلام"; +"redeem.error.code" = "يجب أن يتكون الرمز من %lu خانات رقمية."; +"redeem.error.allfields" = "يرجى كتابة بريدك الإلكتروني ورمز PIN الخاص بالبطاقة."; +"redeem.accessibility.back" = "عودة"; +"redeem.giftcard.placeholder" = "رمز PIN الخاص بالبطاقة."; + +"plan.monthly.title" = "شهريًا"; +"plan.yearly.title" = "سنويًا"; +"plan.yearly.detail_format" = "%@%@ في السنة"; +"plan.price_format" = "%@ / شهر"; +"plan.best_value" = "أفضل قيمة"; +"plan.accessibility.per_month" = "في الشهر"; + +"restore.title" = "استرداد الشراء غير المقيد في الحساب"; +"restore.subtitle" = "إذا اشتريت خطة من خلال هذا التطبيق ولم تصلك بيانات تسجيل دخولك، يمكنك إرسالها مرة أخرى من هنا. لن يتم تحصيل رسوم منك أثناء هذه العملية."; +"restore.email.placeholder" = "البريد الإلكتروني"; +"restore.submit" = "تأكيد"; + +"iap.error.message.unavailable" = "خوادم أبل غير متاحة حاليًا. يرجى إعادة المحاولة لاحقًا."; +"iap.error.title" = "خطأ"; + +"agreement.trials.title" = "شروط وأحكام الفترات التجريبية المجانية"; +"agreement.trials.message" = "سيتم تحصيل مبلغ الدفع من حساب Apple ID الخاص بك عند تأكيد الشراء. يتم تجديد الاشتراك تلقائيًا ما لم يتم إلغاؤه قبل نهاية الفترة الحالية بمدة 24 ساعة على الأقل. سيتم محاسبتك على التجديد خلال 24 ساعة قبل نهاية الفترة الحالية. يمكنك إدارة وإلغاء اشتراكاتك عن طريق الانتقال إلى إعدادات حسابك في متجر التطبيقات بعد الشراء.\n\nقد توفر بعض الاشتراكات المدفوعة فترة تجريبية مجانية قبل تحصيل المبلغ من طريقة الدفع. إذا قررت إلغاء الاشتراك من اشتراك مدفوع قبل البدء في تحصيل الرسوم من طريقة الدفع، قم بإلغاء الاشتراك قبل انتهاء الفترة التجريبية المجانية بمدة 24 ساعة على الأقل.\n\nلا يتم توفير التجارب المجانية إلا للمستخدمين الجدد فقط، وهي وفقًا لتقديرنا الخاص، وإذا حاولت التسجيل للحصول على فترة تجريبية مجانية إضافية، فستتم محاسبتك فورًا على رسوم الاشتراك القياسية.\n\nنحن نحتفظ بالحق في إلغاء الفترة التجريبية المجانية في أي وقت.\n\nسيتم مصادرة أي جزء غير مستخدم من الفترة التجريبية المجانية عند شراء اشتراك.\n\nيمثل التسجيل قبولًا لهذه الشروط والأحكام."; +"agreement.message" = "بعد انتهاء الـ 7 أيام الخاصة بالفترة التجريبية المجانية، يتم تجديد هذا الاشتراك تلقائيًا مقابل %@ ما لم يتم إلغاؤه قبل 24 ساعة على الأقل من نهاية الفترة التجريبية. ستتم محاسبة حساب Apple ID الخاص بك على رسوم التجديد في غضون 24 ساعة قبل نهاية الفترة التجريبية. يمكنك إدارة وإلغاء اشتراكاتك عن طريق الانتقال إلى إعدادات حسابك في App Store بعد الشراء. يقتصر عرض الفترة التجريبية لمدة 7 أيام على عرض فترة تجريبية واحد لمدة 7 أيام لكل مستخدم. أي جزء غير مستخدم من الفترة التجريبية المجانية، إذا تم عرضها، سيتم مصادرته عندما يشتري المستخدم اشتراكًا. تشمل جميع الأسعار ضرائب المبيعات المحلية المطبقة.\n\nيعتبر الاشتراك بمثابة قبول $1 و$2."; +"agreement.trials.yearly.plan" = "سنة"; +"agreement.trials.monthly.plan" = "شهر"; + +"agreement.message.tos" = "شروط الخدمة"; +"agreement.message.privacy" = "سياسة الخصوصية"; + +"getstarted.buttons.buyaccount" = "شراء حساب"; + +"gdpr.collect.data.title" = "المعلومات الشخصية التي نجمعها"; +"gdpr.collect.data.description" = "عنوان البريد الإلكتروني لأغراض إدارة الحساب والحماية من إساءة الاستخدام."; +"gdpr.usage.data.title" = "استخدامات المعلومات الشخصية التي نجمعها"; +"gdpr.usage.data.description" = "يتم استخدام عنوان البريد الإلكتروني لإرسال معلومات الاشتراك وتأكيد الدفع ومراسلات العملاء والعروض الترويجية الخاصة بـ Private Internet Access فقط."; +"gdpr.accept.button.title" = "موافق ومتابعة"; + +"update.account.email.error" = "تعذَّر تعديل البريد الإلكتروني للحساب"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings new file mode 100644 index 000000000..44c000115 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Bekræft tilmelding"; +"in_progress.message" = "Vi bekræfter dit køb i vores system. Det kan tage et øjeblik, så bliv her venligst."; +"in_progress.redeem.message" = "Vi bekræfter din kort-pinkode i vores system. Det kan tage et øjeblik, så bliv her venligst."; + +"success.title" = "Køb fuldført"; +"success.message_format" = "Tak fordi du tilmeldte dig hos os. Vi har sendt dit brugernavn og kodeord til din e-mailadresse %@"; +"success.redeem.title" = "Kort indløst med succes"; +"success.redeem.message" = "Du modtager snart en e-mail med dit brugernavn og adgangskode.\n\nDine loginoplysninger"; +"success.username.caption" = "Brugernavn"; +"success.password.caption" = "Kodeord"; +"success.submit" = "Kom i gang"; + +"failure.vc_title" = "Tilmelding mislykkedes"; +"failure.title" = "Kunne ikke oprette konto"; +"failure.message" = "Vi kan ikke oprette en konto på nuværende tidspunkt. Prøv igen senere.\n\nGenåbning af appen vil genoptage forsøget på at oprette en konto."; +"failure.purchase.sandbox.message" = "Det valgte sandbox-abonnement er ikke tilgængeligt i produktionen."; +"failure.redeem.invalid.title" = "Ugyldig kort-pinkode"; +"failure.redeem.invalid.message" = "Det ser ud til, at du har indtastet en ugyldig kort-pinkode. Prøv igen."; +"failure.redeem.claimed.title" = "Kort allerede taget"; +"failure.redeem.claimed.message" = "Det ser ud til, at dette kort allerede er taget af en anden konto. Prøv at indtaste en anden pinkode."; +"failure.submit" = "GÅ TILBAGE"; + +"unreachable.vc_title" = "Fejl"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Ingen internetforbindelse fundet. Bekræft venligst, at du har en internetforbindelse, og tryk på \"prøv igen\" herunder.\n\nDu kan vende tilbage til appen senere for at afslutte processen."; +"unreachable.submit" = "PRØV IGEN"; + +"purchase.uncredited.alert.message" = "Du har ukrediterede transaktioner. Vil du gendanne dine kontooplysninger?"; +"purchase.uncredited.alert.button.cancel" = "Annuller"; +"purchase.uncredited.alert.button.recover" = "Gendan konto"; + +"purchase.trials.intro" = "Start din 7-dages gratis prøveperiode"; +"purchase.trials.price.after" = "Derefter %@"; +"purchase.trials.money.back" = "30-dages pengene tilbage garanti"; +"purchase.trials.1year.protection" = "1 års beskyttelse af personlige oplysninger og identitet"; +"purchase.trials.anonymous" = "Gennemse anonymt og skjul din ip."; +"purchase.trials.devices" = "Understøtter 10 enheder på én gang"; +"purchase.trials.devices.description" = "Beskyt dig selv på op til 10 enheder ad gangen."; +"purchase.trials.region" = "Forbind nemt til en hvilken som helst region"; +"purchase.trials.servers" = "Mere end 3300 servere i 32 lande"; +"purchase.trials.start" = "Start abonnement"; +"purchase.trials.all.plans" = "Se alle tilgængelige planer"; + +"purchase.subscribe.now" = "Tilmeld nu"; + +// WALKTHROUGH + +"walkthrough.action.next" = "NÆSTE"; +"walkthrough.action.done" = "UDFØRT"; +"walkthrough.action.skip" = "SPRING OVER"; + +"walkthrough.page.1.title" = "Understøtter 10 enheder på en gang"; +"walkthrough.page.1.description" = "Beskyt dig selv på op til 10 enheder ad gangen."; +"walkthrough.page.2.title" = "Forbind nemt til en hvilken som helst region"; +"walkthrough.page.2.description" = "Med servere rundt om i verden er du altid beskyttet."; +"walkthrough.page.3.title" = "Beskyt dig mod annoncer"; +"walkthrough.page.3.description" = "Aktivering af vores Indholdsblokering forhindrer reklamer i at blive vist i Safari."; + +"share.data.buttons.accept" = "Accepter"; +"share.data.buttons.noThanks" = "Nej tak"; +"share.data.buttons.readMore" = "Læs mere"; +"share.data.text.title" = "Hjælp os med at forbedre vores service"; +"share.data.text.description" = "For at hjælpe os med at sikre vores tjenestes forbindelsesydelse, kan du anonymt dele dine forbindelsesstatistikker med os. Disse rapporter inkluderer ikke personligt identificerbare oplysninger."; +"share.data.text.footer" = "Du kan altid kontrollere dette fra dine indstillinger"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/da.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/da.lproj/UI.strings new file mode 100644 index 000000000..ef42d7faf --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/da.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Luk"; +"global.ok" = "OK"; +"global.cancel" = "Annuller"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings new file mode 100644 index 000000000..6e179a032 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Log ind på din konto"; +"login.username.placeholder" = "Brugernavn (p1234567)"; +"login.password.placeholder" = "Kodeord"; +"login.submit" = "LOG IND"; +"login.restore.button" = "Modtog du ikke dine kontodetaljer?"; +"login.error.title" = "Log ind"; +"login.error.validation" = "Du skal indtaste et brugernavn og et kodeord."; +"login.error.unauthorized" = "Dit brugernavn eller kodeord er forkert."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Log på med købskvittering"; +"login.magic.link.title" = "Log ind ved hjælp af magisk e-maillink"; +"login.magic.link.response" = "Se i din e-mail for et login-link."; +"login.magic.link.send" = "Send link"; +"login.magic.link.invalid.email" = "Ugyldig e-mail. Prøv igen."; + +"purchase.title" = "Vælg en VPN-plan"; +"purchase.subtitle" = "30-dages pengene tilbage garanti"; +"purchase.email.placeholder" = "E-mailadresse"; +"purchase.continue" = "Fortsæt"; +"purchase.login.footer" = "Har du allerede en konto?"; +"purchase.login.button" = "Log ind"; +"purchase.error.title" = "Køb"; +"purchase.error.validation" = "Du skal indtaste en e-mailadresse"; +"purchase.error.connectivity.title" = "Forbindelsesfejl"; +"purchase.error.connectivity.description" = "Vi kan ikke nå Private Internet Access. Dette kan skyldes dårlig internet eller at vores service er blokeret i dit land."; +"purchase.confirm.form.email" = "Indtast din e-mailadresse"; +"purchase.confirm.plan" = "Du køber %@-planen"; +"purchase.email.why" = "Vi har brug for din e-mail for at sende dit brugernavn og din adgangskode."; +"purchase.submit" = "Indsend"; +"purchase.or" = "eller"; + +"upgrade.header" = "Velkommen tilbage!"; +"upgrade.title" = "For at bruge Private Internet Access skal du forny dit abonnement."; +"upgrade.renew.now" = "Forny nu"; + + + +"redeem.title" = "Indløs gavekort"; +"redeem.subtitle" = "Indtast din e-mailadresse, og %lu-cifrede pinkode frra dit gavekort eller prøvekort herunder."; +"redeem.email.placeholder" = "E-mailadresse"; +"redeem.submit" = "INDSEND"; +"redeem.error.title" = "Indløs"; +"redeem.error.code" = "Koden skal være %lu numeriske cifre."; +"redeem.error.allfields" = "Indtast venligst din e-mail og dit korts PIN-kode."; +"redeem.accessibility.back" = "Tilbage"; +"redeem.giftcard.placeholder" = "Gavekortets PIN-kode"; + +"plan.monthly.title" = "Månedligt"; +"plan.yearly.title" = "Årligt"; +"plan.yearly.detail_format" = "%@%@ per år"; +"plan.price_format" = "%@/mdr"; +"plan.best_value" = "Bedste værdi"; +"plan.accessibility.per_month" = "per måned"; + +"restore.title" = "Gendan ukrediteret køb"; +"restore.subtitle" = "Hvis du har købt en plan gennem denne app og ikke har modtaget dine legitimationsoplysninger, kan du anmode om at sende dem igen herfra. Du vil ikke blive opkrævet i løbet af denne proces."; +"restore.email.placeholder" = "E-mailadresse"; +"restore.submit" = "BEKRÆFT"; + +"iap.error.message.unavailable" = "Apple-servere er ikke tilgængelige i øjeblikket. Prøv venligst igen senere."; +"iap.error.title" = "Fejl"; + +"agreement.trials.title" = "Vilkår og betingelser for gratis prøveperioder"; +"agreement.trials.message" = "Betaling debiteres din Apple ID-konto ved bekræftelsen af ​​købet. Abonnementet fornyes automatisk, medmindre det annulleres mindst 24 timer inden udgangen af ​​den aktuelle periode. Din konto bliver debiteret for fornyelse inden for 24 timer inden udgangen af ​​den aktuelle periode. Du kan administrere og annullere dine abonnementer ved at gå til dine kontoindstillinger i App Store efter køb.\n\nVisse betalte abonnementer kan muligvis tilbyde en gratis prøveperiode, inden de opkræver din betalingsmetode. Hvis du beslutter at afmelde dig et betalt abonnement, før vi begynder at opkræve din betalingsmetode, skal du annullere abonnementet mindst 24 timer før den gratis prøveperiode afsluttes.\n\nGratis prøveperioder er kun tilgængelige for nye brugere og er efter vores eget skøn, og hvis du forsøger at tilmelde dig en ekstra gratis prøveperiode, bliver du straks debiteret for det almindelige abonnementsgebyr.\n\nVi forbeholder os retten til at tilbagekalde din gratis prøveperiode til enhver tid.\n\nEnhver ubrugt del af din gratis prøveperiode fortabes ved køb af et abonnement.\n\nTilmelding udgør accept af disse vilkår og betingelser."; +"agreement.message" = "Efter den gratis prøveperiode på 7 dage, fornyes dette abonnement automatisk for %@, medmindre det annulleres mindst 24 timer før prøveperioden er afsluttet. Din Apple ID-konto bliver debiteret for fornyelse inden for 24 timer inden udløbet af prøveperioden. Du kan administrere og annullere dine abonnementer ved at gå til din App Store-kontoindstillinger efter købet. Tilbudet med en 7-dages prøveperiode er begrænset til en 7-dages prøveperiode pr. bruger. Enhver ubrugt del af en gratis prøveperiode, hvis den tilbydes, fortabes, når brugeren køber et abonnement. Alle priser inkluderer gældende lokal moms.\n\nSigning up constitutes acceptance of the $1 and the $2."; +"agreement.trials.yearly.plan" = "år"; +"agreement.trials.monthly.plan" = "måned"; + +"agreement.message.tos" = "Vilkår for brug"; +"agreement.message.privacy" = "Fortrolighedspolitik"; + +"getstarted.buttons.buyaccount" = "Køb konto"; + +"gdpr.collect.data.title" = "Personlige oplysninger, vi indsamler"; +"gdpr.collect.data.description" = "E-mailadresse med henblik på kontohåndtering og beskyttelse mod misbrug."; +"gdpr.usage.data.title" = "Anvendelse af personlige oplysninger indsamlet af os"; +"gdpr.usage.data.description" = "E-mailadresse bruges kun til at sende abonnementsoplysninger, betalingsbekræftelser, kundekorrespondance og salgsfremmende tilbud fra Private Internet Access."; +"gdpr.accept.button.title" = "Accepter og fortsæt"; + +"update.account.email.error" = "Lykkedes ikke at ændre konto-e-mail"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings new file mode 100644 index 000000000..ba5d2b2b5 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Registrierung bestätigen"; +"in_progress.message" = "Wir bestätigen deinen Kauf in unserem System. Es kann einen Moment dauern, also gedulde dich bitte etwas."; +"in_progress.redeem.message" = "Wir überprüfen derzeit Ihre Karten-PIN in unserem System. Dies kann einen Moment dauern. Bitte haben Sie etwas Geduld."; + +"success.title" = "Kauf abgeschlossen"; +"success.message_format" = "Vielen Dank für deine Registrierung. Wir haben dir deinen Benutzernamen und dein Passwort an deine E-Mail-Adresse unter %@ gesendet."; +"success.redeem.title" = "Karte erfolgreich eingelöst!"; +"success.redeem.message" = "Sie werden in Kürze eine E-Mail mit Ihrem Benutzernamen und Passwort erhalten.\n\nIhre Zugangsdaten"; +"success.username.caption" = "Benutzername"; +"success.password.caption" = "Passwort"; +"success.submit" = "Erste Schritte"; + +"failure.vc_title" = "Registrierung fehlgeschlagen"; +"failure.title" = "Konto nicht erstellt"; +"failure.message" = "Zur Zeit können wir kein Konto erstellen. Bitte später erneut versuchen.\n\nBeim erneuten Öffnen der App wird wieder versucht, ein Konto zu erstellen."; +"failure.purchase.sandbox.message" = "Das ausgewählte Sandbox-Abonnement ist in der Produktion nicht verfügbar."; +"failure.redeem.invalid.title" = "Ungültige Karten-PIN"; +"failure.redeem.invalid.message" = "Anscheinend haben Sie eine ungültige PIN eingegeben. Bitte erneut versuchen."; +"failure.redeem.claimed.title" = "Karte bereits eingelöst"; +"failure.redeem.claimed.message" = "Anscheinend wurde diese Karte bereits über ein anderes Konto eingelöst. Geben Sie eine andere PIN ein."; +"failure.submit" = "ZURÜCK"; + +"unreachable.vc_title" = "Fehler"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Keine Internetverbindung gefunden. Bitte deine Internetverbindung überprüfen und erneut versuchen.\n\nDu kannst die App später erneut aufrufen, um den Vorgang abzuschließen."; +"unreachable.submit" = "WIEDERHOLEN"; + +"purchase.uncredited.alert.message" = "Sie haben Transaktionen, die noch nicht gutgeschrieben wurden. Möchten Sie Ihre Kontodaten wiederherstellen?"; +"purchase.uncredited.alert.button.cancel" = "Abbrechen"; +"purchase.uncredited.alert.button.recover" = "Konto wiederherstellen"; + +"purchase.trials.intro" = "Jetzt 7 Tage gratis testen"; +"purchase.trials.price.after" = "Dann %@"; +"purchase.trials.money.back" = "30-Tage-Geld-zurück-Garantie"; +"purchase.trials.1year.protection" = "1 Jahr Daten- und Identitätsschutz"; +"purchase.trials.anonymous" = "Anonym surfen und Ihre IP-Adresse verbergen"; +"purchase.trials.devices" = "Unterstützung für 10 Geräte"; +"purchase.trials.devices.description" = "Schützen Sie sich auf bis zu 10 Geräten gleichzeitig."; +"purchase.trials.region" = "Einfache Verbindung zu jeder Region"; +"purchase.trials.servers" = "Mehr als 3300 Server in 32 Ländern"; +"purchase.trials.start" = "Abonnement beginnen"; +"purchase.trials.all.plans" = "Alle verfügbaren Pläne anzeigen"; + +"purchase.subscribe.now" = "Jetzt abonnieren"; + +// WALKTHROUGH + +"walkthrough.action.next" = "WEITER"; +"walkthrough.action.done" = "FERTIG"; +"walkthrough.action.skip" = "ÜBERSPRINGEN"; + +"walkthrough.page.1.title" = "Unterstützung für 10 Geräte"; +"walkthrough.page.1.description" = "Schützen Sie sich auf bis zu 10 Geräten gleichzeitig."; +"walkthrough.page.2.title" = "Bequem mit jeder beliebigen Region verbinden"; +"walkthrough.page.2.description" = "Mit Servern auf der ganzen Welt bist du immer geschützt."; +"walkthrough.page.3.title" = "Schütze dich vor Werbung"; +"walkthrough.page.3.description" = "Mit der Aktivierung unseres Inhalts-Blockers sehen Sie keine Anzeigen in Safari mehr."; + +"share.data.buttons.accept" = "Akzeptieren"; +"share.data.buttons.noThanks" = "Nein danke"; +"share.data.buttons.readMore" = "Mehr erfahren"; +"share.data.text.title" = "Bitte helfen Sie uns, unseren Service zu verbessern"; +"share.data.text.description" = "Um uns zu helfen, die Verbindungsleistung unseres Dienstes sicherzustellen, können Sie Ihre Verbindungsstatistiken anonym mit uns teilen. Diese Berichte enthalten keine persönlich identifizierbaren Informationen."; +"share.data.text.footer" = "Sie können dies jederzeit über Ihre Einstellungen steuern"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/de.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/de.lproj/UI.strings new file mode 100644 index 000000000..4268a80ca --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/de.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Schließen"; +"global.ok" = "OK"; +"global.cancel" = "Abbrechen"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings new file mode 100644 index 000000000..ed13eb4ab --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "An deinem Konto anmelden"; +"login.username.placeholder" = "Benutzername (p1234567)"; +"login.password.placeholder" = "Passwort"; +"login.submit" = "ANMELDEN"; +"login.restore.button" = "Keine Kontodaten erhalten?"; +"login.error.title" = "Anmelden"; +"login.error.validation" = "Du musst einen Benutzernamen und ein Passwort angeben."; +"login.error.unauthorized" = "Dein Benutzername oder Passwort ist falsch."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Anmeldung mit Kaufbeleg"; +"login.magic.link.title" = "Anmeldung mit magischem E-Mail-Link"; +"login.magic.link.response" = "Bitte überprüfen Sie Ihre E-Mail auf einen Login-Link."; +"login.magic.link.send" = "Link senden"; +"login.magic.link.invalid.email" = "Ungültige E-Mail-Adresse. Bitte erneut versuchen."; + +"purchase.title" = "VPN-Tarif auswählen"; +"purchase.subtitle" = "30-Tage-Geld-zurück-Garantie"; +"purchase.email.placeholder" = "E-Mail-Adresse"; +"purchase.continue" = "Weiter"; +"purchase.login.footer" = "Bereits ein Konto?"; +"purchase.login.button" = "Anmelden"; +"purchase.error.title" = "Kaufen"; +"purchase.error.validation" = "Sie müssen eine E-Mail-Adresse angeben."; +"purchase.error.connectivity.title" = "Verbindungsfehler"; +"purchase.error.connectivity.description" = "Wir können Private Internet Access nicht erreichen. Dies kann auf eine schlechte Internetverbindung zurückzuführen sein oder unser Service ist in deinem Land blockiert."; +"purchase.confirm.form.email" = "E-Mail-Adresse eingeben"; +"purchase.confirm.plan" = "Sie erwerben den %@-Tarif."; +"purchase.email.why" = "Wir benötigen Ihre E-Mail, um Ihren Benutzernamen und Ihr Passwort zu senden."; +"purchase.submit" = "Senden"; +"purchase.or" = "oder"; + +"upgrade.header" = "Willkommen zurück!"; +"upgrade.title" = "Sie müssen Ihr Abonnement erneuern, um Private Internet Access nutzen zu können."; +"upgrade.renew.now" = "Jetzt erneuern"; + + + +"redeem.title" = "Geschenkkarte einlösen"; +"redeem.subtitle" = "Geben Sie unten Ihre E-Mail-Adresse und die %lu-stellige PIN von Ihrer Geschenk- oder Testkarte ein."; +"redeem.email.placeholder" = "E-Mail-Adresse"; +"redeem.submit" = "SENDEN"; +"redeem.error.title" = "Einlösen"; +"redeem.error.code" = "Der Code muss aus %lu Ziffern bestehen."; +"redeem.error.allfields" = "Bitte geben Sie Ihre E-Mail-Adresse und Karten-PIN ein."; +"redeem.accessibility.back" = "Zurück"; +"redeem.giftcard.placeholder" = "PIN der Geschenkkarte"; + +"plan.monthly.title" = "Monatlich"; +"plan.yearly.title" = "Jährlich"; +"plan.yearly.detail_format" = "%@%@ pro Jahr"; +"plan.price_format" = "%@/Monat"; +"plan.best_value" = "Bestpreis"; +"plan.accessibility.per_month" = "pro Monat"; + +"restore.title" = "Nicht gutgeschriebenen Kauf wiederherstellen"; +"restore.subtitle" = "Wenn Sie einen Tarif über diese App erworben haben und Ihre Zugangsdaten nicht erhalten haben, können Sie sie hier erneut anfordern. Sie müssen dann nicht erneut bezahlen."; +"restore.email.placeholder" = "E-Mail-Adresse"; +"restore.submit" = "BESTÄTIGEN"; + +"iap.error.message.unavailable" = "Die Apple-Server sind momentan nicht verfügbar. Bitte später erneut versuchen."; +"iap.error.title" = "Fehler"; + +"agreement.trials.title" = "Nutzungsbedingungen für kostenlose Testversionen"; +"agreement.trials.message" = "Die Zahlung wird Ihrem Apple ID-Konto bei der Kaufbestätigung belastet. Das Abonnement verlängert sich automatisch, wenn es nicht mindestens 24 Stunden vor Ablauf der aktuellen Periode gekündigt wird. Die Verlängerung wird Ihrem Konto innerhalb von 24 Stunden vor Ablauf der aktuellen Periode in Rechnung gestellt. Sie können Ihre Abonnements verwalten und kündigen, indem Sie nach dem Kauf zu Ihren Kontoeinstellungen im App Store aufrufen.\n\nBestimmte kostenpflichtige Abonnements können eine kostenlose Testversion anbieten, bevor Sie Ihre Zahlungsmethode berechnen. Wenn Sie sich entscheiden, sich von einem kostenpflichtigen Abonnement abzumelden, bevor wir mit der Berechnung Ihrer Zahlungsmethode beginnen, kündigen Sie das Abonnement mindestens 24 Stunden vor Ablauf der kostenlosen Probezeit.\n\nKostenlose Testversionen sind nur für neue Benutzer verfügbar und liegen in unserem alleinigen Ermessen, und wenn Sie versuchen, sich für eine zusätzliche kostenlose Testversion anzumelden, wird Ihnen sofort die Standard-Abonnementgebühr in Rechnung gestellt.\n\nWir behalten uns das Recht vor, Ihre kostenlose Testversion jederzeit zu widerrufen.\n\nJeder ungenutzte Teil Ihrer kostenlosen Probezeit verfällt mit dem Kauf eines Abonnements.\n\nMit der Registrierung akzeptieren Sie diese Nutzungsbedingungen."; +"agreement.message" = "Nach der 7-tägigen kostenlosen Testperiode verlängert sich dieses Abonnement automatisch für %@, sofern es nicht mindestens 24 Stunden vor Ablauf der Testperiode gekündigt wird. Ihr Apple-ID-Konto wird für die Verlängerung innerhalb von 24 Stunden vor Ablauf des Testzeitraums belastet. Sie können Ihre Abonnements nach dem Kauf in den Einstellungen Ihres App Store-Kontos verwalten und kündigen. Jeder Benutzer kann die 7-tägige kostenlose Testperiode nur einmal in Anspruch nehmen. Jeder nicht genutzte Teil einer kostenlosen Testperiode, falls angeboten, verfällt beim Kauf eines Abonnements durch den Benutzer. Alle Preise enthalten die örtlich geltenden Verkaufssteuern.\n\nMit der Anmeldung akzeptieren Sie die $1 und $2."; +"agreement.trials.yearly.plan" = "Jahr"; +"agreement.trials.monthly.plan" = "Monat"; + +"agreement.message.tos" = "Nutzungsbedingungen"; +"agreement.message.privacy" = "Datenschutzrichtlinien"; + +"getstarted.buttons.buyaccount" = "Konto kaufen"; + +"gdpr.collect.data.title" = "Art der personenbezogenen Daten, die wir erfassen"; +"gdpr.collect.data.description" = "E-Mail-Adresse zum Zwecke der Kontoverwaltung und zum Schutz vor Missbrauch."; +"gdpr.usage.data.title" = "Verwendungszwecke für personenbezogene Daten, die von uns erfasst wurden"; +"gdpr.usage.data.description" = "Die E-Mail-Adresse wird lediglich zum Senden von Abonnementinformationen, Zahlungsbestätigungen, Kundenkorrespondenz und Sonderangeboten zu Private Internet Access verwendet."; +"gdpr.accept.button.title" = "Zustimmen und fortfahren"; + +"update.account.email.error" = "Konto-E-Mail nicht geändert"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings new file mode 100644 index 000000000..dacff3d57 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirm sign-up"; +"in_progress.message" = "We're confirming your purchase with our system. It could take a moment so hang in there."; +"in_progress.redeem.message" = "We're confirming your card PIN with our system. It could take a moment so hang in there."; + +"success.title" = "Purchase complete"; +"success.message_format" = "Thank you for signing up with us. We have sent your account username and password at your email address at %@"; +"success.redeem.title" = "Card redeemed successfully"; +"success.redeem.message" = "You will receive an email shortly with your username and password.\n\nYour login details"; +"success.username.caption" = "Username"; +"success.password.caption" = "Password"; +"success.submit" = "GET STARTED"; + +"failure.vc_title" = "Sign-up failed"; +"failure.title" = "Account creation failed"; +"failure.message" = "We're unable to create an account at this time. Please try again later. Reopening the app will re-attempt to create an account."; +"failure.purchase.sandbox.message" = "The selected sandbox subscription is not available in production."; +"failure.redeem.invalid.title" = "Invalid card PIN"; +"failure.redeem.invalid.message" = "Looks like you entered an invalid card PIN. Please try again."; +"failure.redeem.claimed.title" = "Card claimed already"; +"failure.redeem.claimed.message" = "Looks like this card has already been claimed by another account. You can try entering a different PIN."; +"failure.submit" = "GO BACK"; + +"unreachable.vc_title" = "Error"; +"unreachable.title" = "Whoops!"; +"unreachable.message" = "No internet connection found. Please confirm that you have an internet connection and hit retry below.\n\nYou can come back to the app later to finish the process."; +"unreachable.submit" = "TRY AGAIN"; + +"purchase.uncredited.alert.message" = "You have uncredited transactions. Do you want to recover your account details?"; +"purchase.uncredited.alert.button.cancel" = "Cancel"; +"purchase.uncredited.alert.button.recover" = "Recover account"; + +"purchase.trials.intro" = "Start your 7-day free trial"; +"purchase.trials.price.after" = "Then %@"; +"purchase.trials.money.back" = "30 day money back guarantee"; +"purchase.trials.1year.protection" = "1 year of privacy and identity protection"; +"purchase.trials.anonymous" = "Browse anonymously and hide your ip."; +"purchase.trials.devices" = "Support 10 devices at once"; +"purchase.trials.devices.description" = "Protect yourself on up to 10 devices at a time."; +"purchase.trials.region" = "Connect to any region easily"; +"purchase.trials.servers" = "More than 3300 servers in 32 countries"; +"purchase.trials.start" = "Start subscription"; +"purchase.trials.all.plans" = "See all available plans"; + +"purchase.subscribe.now" = "Subscribe now"; + +// WALKTHROUGH + +"walkthrough.action.next" = "NEXT"; +"walkthrough.action.done" = "DONE"; +"walkthrough.action.skip" = "SKIP"; + +"walkthrough.page.1.title" = "Support 10 devices at once"; +"walkthrough.page.1.description" = "Protect yourself on up to 10 devices at a time."; +"walkthrough.page.2.title" = "Connect to any region easily"; +"walkthrough.page.2.description" = "With servers around the globe, you are always under protection."; +"walkthrough.page.3.title" = "Protect yourself from ads"; +"walkthrough.page.3.description" = "Enabling our Content Blocker prevents ads from showing in Safari."; + +"share.data.buttons.accept" = "Accept"; +"share.data.buttons.noThanks" = "No, thanks"; +"share.data.buttons.readMore" = "Read more"; +"share.data.text.title" = "Please help us improve our service"; +"share.data.text.description" = "To help us ensure our service's connection performance, you can anonymously share your connection stats with us. These reports do not include any personally identifiable information."; +"share.data.text.footer" = "You can always control this from your settings"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/en.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/en.lproj/UI.strings new file mode 100644 index 000000000..98ec3d5e2 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/en.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Close"; +"global.ok" = "OK"; +"global.cancel" = "Cancel"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings new file mode 100644 index 000000000..91c5c4c53 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Sign in to your account"; +"login.username.placeholder" = "Username (p1234567)"; +"login.password.placeholder" = "Password"; +"login.submit" = "LOGIN"; +"login.restore.button" = "Didn't receive account details?"; +"login.error.title" = "Log in"; +"login.error.validation" = "You must enter a username and password."; +"login.error.unauthorized" = "Your username or password is incorrect."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Login using purchase receipt"; +"login.magic.link.title" = "Login using magic email link"; +"login.magic.link.response" = "Please check your e-mail for a login link."; +"login.magic.link.send" = "Send Link"; +"login.magic.link.invalid.email" = "Invalid email. Please try again."; + +"purchase.title" = "Select a VPN plan"; +"purchase.subtitle" = "30-day money back guarantee"; +"purchase.email.placeholder" = "Email address"; +"purchase.continue" = "Continue"; +"purchase.login.footer" = "Already have an account?"; +"purchase.login.button" = "Sign in"; +"purchase.error.title" = "Purchase"; +"purchase.error.validation" = "You must enter an email address."; +"purchase.error.connectivity.title" = "Connection Failure"; +"purchase.error.connectivity.description" = "We are unable to reach Private Internet Access. This may due to poor internet or our service is blocked in your country."; +"purchase.confirm.form.email" = "Enter your email address"; +"purchase.confirm.plan" = "You are purchasing the %@ plan"; +"purchase.email.why" = "We need your email to send your username and password."; +"purchase.submit" = "Submit"; +"purchase.or" = "or"; + +"upgrade.header" = "Welcome Back!"; +"upgrade.title" = "In order to use Private Internet Access, you’ll need to renew your subscription."; +"upgrade.renew.now" = "Renew now"; + + + +"redeem.title" = "Redeem gift card"; +"redeem.subtitle" = "Type in your email address and the %lu digit PIN from your gift card or trial card below."; +"redeem.email.placeholder" = "Email address"; +"redeem.submit" = "SUBMIT"; +"redeem.error.title" = "Redeem"; +"redeem.error.code" = "Code must be %lu numeric digits."; +"redeem.error.allfields"="Please type in your email and card PIN."; +"redeem.accessibility.back" = "Back"; +"redeem.giftcard.placeholder" = "Gift card PIN"; + +"plan.monthly.title" = "Monthly"; +"plan.yearly.title" = "Yearly"; +"plan.yearly.detail_format" = "%@%@ per year"; +"plan.price_format" = "%@/mo"; +"plan.best_value" = "Best value"; +"plan.accessibility.per_month" = "per month"; + +"restore.title" = "Restore uncredited purchase"; +"restore.subtitle" = "If you purchased a plan through this app and didn't receive your credentials, you can send them again from here. You will not be charged during this process."; +"restore.email.placeholder" = "Email address"; +"restore.submit" = "CONFIRM"; + +"iap.error.message.unavailable" = "Apple servers currently unavailable. Please try again later."; +"iap.error.title" = "Error"; + +"agreement.trials.title" = "Free trials terms and conditions"; +"agreement.trials.message" = "Payment will be charged to your Apple ID account at the confirmation of purchase. Subscription automatically renews unless it is canceled at least 24 hours before the end of the current period. Your account will be charged for renewal within 24 hours prior to the end of the current period. You can manage and cancel your subscriptions by going to your account settings on the App Store after purchase.\n\nCertain Paid Subscriptions may offer a free trial prior to charging your payment method. If you decide to unsubscribe from a Paid Subscription before we start charging your payment method, cancel the subscription at least 24 hours before the free trial ends.\n\nFree trials are only available to new users, and are at our sole discretion, and if you attempt to sign up for an additional free trial, you will be immediately charged with the standard Subscription Fee.\n\nWe reserve the right to revoke your free trial at any time.\n\nAny unused portion of your free trial period will be forfeited upon purchase of a subscription.\n\nSigning up constitutes acceptance of this terms and conditions."; +"agreement.message" = "After the 7 days free trial this subscription automatically renews for %@ unless it is canceled at least 24 hours before the end of the trial period. Your Apple ID account will be charged for renewal within 24 hours before the end of the trial period. You can manage and cancel your subscriptions by going to your App Store account settings after purchase. 7-days trial offer is limited to one 7-days trial offer per user. Any unused portion of a free trial period, if offered, will be forfeited when the user purchases a subscription. All prices include applicable local sales taxes.\n\nSigning up constitutes acceptance of the $1 and the $2."; +"agreement.trials.yearly.plan" = "year"; +"agreement.trials.monthly.plan" = "month"; + +"agreement.message.tos" = "Terms of Service"; +"agreement.message.privacy" = "Privacy Policy"; + +"getstarted.buttons.buyaccount" = "Buy account"; + +"gdpr.collect.data.title" = "Personal information we collect"; +"gdpr.collect.data.description" = "E-mail Address for the purposes of account management and protection from abuse."; +"gdpr.usage.data.title" = "Uses of personal information collected by us"; +"gdpr.usage.data.description" = "E-mail address is used to send subscription information, payment confirmations, customer correspondence, and Private Internet Access promotional offers only."; +"gdpr.accept.button.title" = "Agree and continue"; + +"update.account.email.error" = "Failed to modify account email"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings new file mode 100644 index 000000000..3ebdb9fd3 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirmar registro"; +"in_progress.message" = "Estamos confirmando la compra en el sistema. Podrías tardar unos instantes, así que espera."; +"in_progress.redeem.message" = "Estamos confirmando el PIN de tu tarjeta en nuestro sistema. Puede tardar un momento, así que espera un poco."; + +"success.title" = "Compra completa"; +"success.message_format" = "Gracias por registrarte con nosotros. Te enviamos el nombre de usuario y contraseña de tu cuenta a tu dirección de email en %@"; +"success.redeem.title" = "Tarjeta canjeada correctamente"; +"success.redeem.message" = "Recibirás un mensaje de correo electrónico dentro de poco con tu nombre de usuario y contraseña.\n\nTu información de inicio de sesión"; +"success.username.caption" = "Nombre de usuario"; +"success.password.caption" = "Contraseña "; +"success.submit" = "Empieza"; + +"failure.vc_title" = "Falló el registro"; +"failure.title" = "Falló la creación de la cuenta"; +"failure.message" = "No pudimos crear una cuenta en este momento. Por favor, inténtalo de nuevo más tarde. \nSi vuelves a abrir la aplicación intentaremos crear una cuenta otra vez."; +"failure.purchase.sandbox.message" = "La suscripción del entorno aislado seleccionado no está disponible en la producción."; +"failure.redeem.invalid.title" = "El PIN de la tarjeta no es válido"; +"failure.redeem.invalid.message" = "Parece que ingresaste un PIN de tarjeta inválido. Por favor, inténtalo de nuevo."; +"failure.redeem.claimed.title" = "La tarjeta ya fue reclamada"; +"failure.redeem.claimed.message" = "Parece que esta tarjeta ha sido reclamada por otra cuenta. Puedes intentar ingresar un PIN diferente."; +"failure.submit" = "ATRÁS"; + +"unreachable.vc_title" = "Error"; +"unreachable.title" = "¡Ups!"; +"unreachable.message" = "No se encontró conexión a Internet. Por favor, confirma que tienes una conexión a Internet y toca en intentar de nuevo más abajo.\n\nPuedes regresar después a la aplicación para terminar el proceso."; +"unreachable.submit" = "VOLVER A INTENTAR"; + +"purchase.uncredited.alert.message" = "Tienes transacciones sin acreditar. ¿Seguro que quieres recuperar los detalles de tu cuenta?"; +"purchase.uncredited.alert.button.cancel" = "Cancelar"; +"purchase.uncredited.alert.button.recover" = "Recuperar cuenta"; + +"purchase.trials.intro" = "Inicia tu prueba gratuita de 7 días"; +"purchase.trials.price.after" = "Después, %@"; +"purchase.trials.money.back" = "Garantía de devolución de 30 días"; +"purchase.trials.1year.protection" = "1 año de privacidad y protección de la identidad."; +"purchase.trials.anonymous" = "Navega de forma anónima y oculta tu IP."; +"purchase.trials.devices" = "Admite 10 dispositivos a la vez."; +"purchase.trials.devices.description" = "Protégete en hasta 10 dispositivos a la vez."; +"purchase.trials.region" = "Conéctate a cualquier región con facilidad."; +"purchase.trials.servers" = "Más de 3300 servidores en 32 países."; +"purchase.trials.start" = "Iniciar suscripción"; +"purchase.trials.all.plans" = "Ver todos los planes disponibles."; + +"purchase.subscribe.now" = "Suscríbete ahora"; + +// WALKTHROUGH + +"walkthrough.action.next" = "SIGUIENTE"; +"walkthrough.action.done" = "TERMINADO"; +"walkthrough.action.skip" = "OMITIR"; + +"walkthrough.page.1.title" = "Admite 10 dispositivos a la vez"; +"walkthrough.page.1.description" = "Protégete en hasta 10 dispositivos a la vez."; +"walkthrough.page.2.title" = "Conéctate a cualquier región con facilidad"; +"walkthrough.page.2.description" = "Con servidores en todo el mundo, siempre estarás protegido."; +"walkthrough.page.3.title" = "Protégete de la publicidad"; +"walkthrough.page.3.description" = "Habilita nuestro Bloqueador de contenido para impedir que aparezca publicidad en Safari."; + +"share.data.buttons.accept" = "Aceptar"; +"share.data.buttons.noThanks" = "No, gracias"; +"share.data.buttons.readMore" = "Más información"; +"share.data.text.title" = "Ayúdanos a mejorar nuestro servicio."; +"share.data.text.description" = "Para ayudarnos a garantizar el rendimiento de la conexión de nuestro servicio, puedes compartir con nosotros tus estadísticas de conexión de forma anónima. Estos informes no contienen ninguna información personal identificable."; +"share.data.text.footer" = "Siempre puedes controlarlo desde tus ajustes."; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings new file mode 100644 index 000000000..e645f72b5 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versión %@ (%@)"; +"global.close" = "Cerrar"; +"global.ok" = "Aceptar"; +"global.cancel" = "Cancelar"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings new file mode 100644 index 000000000..3c47f73e3 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Inicia sesión en tu cuenta"; +"login.username.placeholder" = "Nombre de usuario (p1234567)"; +"login.password.placeholder" = "Contraseña "; +"login.submit" = "INICIAR SESIÓN"; +"login.restore.button" = "¿No has recibido los detalles de la cuenta?"; +"login.error.title" = "Iniciar sesión"; +"login.error.validation" = "Debe ingresar un nombre de usuario y una contraseña."; +"login.error.unauthorized" = "Tu nombre de usuario o contraseña son incorrectos."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Inicia sesión con el recibo de compra"; +"login.magic.link.title" = "Inicia sesión con el vínculo mágico del correo electrónico."; +"login.magic.link.response" = "Busca en tu correo electrónico un enlace de inicio de sesión."; +"login.magic.link.send" = "Enviar enlace"; +"login.magic.link.invalid.email" = "Correo electrónico no válido. Vuelve a intentarlo."; + +"purchase.title" = "Selecciona un plan VPN"; +"purchase.subtitle" = "Garantía de devolución de 30 días"; +"purchase.email.placeholder" = "Dirección de correo electrónico"; +"purchase.continue" = "Continuar"; +"purchase.login.footer" = "¿Ya tienes una cuenta?"; +"purchase.login.button" = "Inicia sesión"; +"purchase.error.title" = "Comprar"; +"purchase.error.validation" = "Debes ingresar una dirección de email."; +"purchase.error.connectivity.title" = "Falla en la conexión"; +"purchase.error.connectivity.description" = "No pudimos localizar a Private Internet Access. Esto puede ser debido a una mala conexión con Internet o a que nuestro servicio está bloqueado en su país."; +"purchase.confirm.form.email" = "Introduce tu dirección de correo electrónico"; +"purchase.confirm.plan" = "Estás comprando el plan %@."; +"purchase.email.why" = "Necesitamos tu dirección de correo electrónico para enviar tu nombre de usuario y tu contraseña."; +"purchase.submit" = "Enviar"; +"purchase.or" = "o"; + +"upgrade.header" = "¡Hola otra vez!"; +"upgrade.title" = "Para usar Private Internet Access debes renovar tu suscripción."; +"upgrade.renew.now" = "Renovar ahora"; + + + +"redeem.title" = "Canjear tarjeta de regalo"; +"redeem.subtitle" = "Escribe abajo tu dirección de correo electrónico y el PIN de %lu dígitos de tu tarjeta de regalo o tarjeta de prueba."; +"redeem.email.placeholder" = "Dirección de correo electrónico"; +"redeem.submit" = "ENVIAR"; +"redeem.error.title" = "Canjear"; +"redeem.error.code" = "El código debe tener %lu dígitos numéricos."; +"redeem.error.allfields" = "Escribe tu dirección de correo electrónico y el PIN de tu tarjeta."; +"redeem.accessibility.back" = "Volver"; +"redeem.giftcard.placeholder" = "PIN de tarjeta regalo"; + +"plan.monthly.title" = "Mensual"; +"plan.yearly.title" = "Anual"; +"plan.yearly.detail_format" = "%@%@ al año"; +"plan.price_format" = "%@/m"; +"plan.best_value" = "Mejor oferta"; +"plan.accessibility.per_month" = "por mes"; + +"restore.title" = "Restablecer compra no acreditada"; +"restore.subtitle" = "Si compraste un plan a través de esta aplicación y no recibes tus credenciales, puedes reiniciar la renovación desde aquí. No se realizarán cargos durante este proceso. \n"; +"restore.email.placeholder" = "Correo electrónico"; +"restore.submit" = "CONFIRMAR"; + +"iap.error.message.unavailable" = "Actualmente, los servidores de Apple no están disponibles. Por favor, inténtalo de nuevo más tarde."; +"iap.error.title" = "Error"; + +"agreement.trials.title" = "Términos y condiciones de la prueba gratuita."; +"agreement.trials.message" = "Se realizará un cobro en tu cuenta de Apple ID en el momento de confirmar la compra. Las suscripciones se renuevan automáticamente a menos que se cancelen como mínimo 24 horas antes de la finalización del periodo actual. Se cobrará la cantidad de la renovación en un plazo de 24 horas antes de la finalización del período actual. Tu mismo podrás gestionar y cancelar las suscripciones en los ajustes de App Store después de la compra. \n\nAlgunas suscripciones de pago pueden ofrecer una prueba gratuita antes de realizar cobros según tu método de pago. Si decides darte de baja de una suscripción de pago antes de que comencemos a cobrar tu método de pago, cancela la suscripción al menos 24 horas antes de que finalice la prueba gratuita.\n\nLas pruebas gratuitas solo están disponibles para nuevos usuarios y quedan a nuestra entera discreción. Si intentas registrarte para obtener una prueba gratuita adicional, se te cobrará de inmediato la tarifa de suscripción estándar.\n\nNos reservamos el derecho de revocar tu prueba gratuita en cualquier momento.\n\nLas secciones sin usar del periodo de prueba gratuito se perderán si el usuario compra una suscripción.\n\nSi te registras, aceptas estos términos y condiciones."; +"agreement.message" = "Después de los 7 días de prueba gratuita, esta suscripción se renueva automáticamente por %@ a menos que se cancele al menos 24 horas antes del final del período de prueba. Se cobrará la renovación en tu cuenta de ID de Apple en un plazo de 24 horas antes de que finalice el periodo de prueba. Puedes gestionar y cancelar tus suscripciones accediendo a los ajustes de tu cuenta de App Store después de la compra. La oferta de prueba de 7 días se limita a una oferta de prueba de 7 días por usuario. Cualquier parte no utilizada de un período de prueba gratuito, si se ofrece, se perderá cuando el usuario compre una suscripción. Todos los precios incluyen los impuestos de venta locales aplicables.\n\nSi te registras, aceptas los $1 y la $2."; +"agreement.trials.yearly.plan" = "año"; +"agreement.trials.monthly.plan" = "mes"; + +"agreement.message.tos" = "Términos de servicio"; +"agreement.message.privacy" = "Política de privacidad"; + +"getstarted.buttons.buyaccount" = "Comprar cuenta"; + +"gdpr.collect.data.title" = "Información personal que recopilamos"; +"gdpr.collect.data.description" = "Dirección de correo electrónico con fines de gestión de cuenta y protección frente a abusos."; +"gdpr.usage.data.title" = "Usos de la información personal que recopilamos"; +"gdpr.usage.data.description" = "La dirección de correo electrónico solo se usa para enviar información de suscripción, confirmaciones de pago, correspondencia al cliente y ofertas promocionales de Private Internet Access."; +"gdpr.accept.button.title" = "Aceptar y continuar"; + +"update.account.email.error" = "Error al modificar el correo electrónico de la cuenta"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings new file mode 100644 index 000000000..a99c30197 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirmation d'inscription"; +"in_progress.message" = "Notre système est en train de confirmer votre achat. Cela pourrait prendre un moment, nous vous prions donc de patienter."; +"in_progress.redeem.message" = "Notre système est en train de confirmer le code PIN de votre carte. Cela pourrait prendre un moment, nous vous prions donc de patienter."; + +"success.title" = "Achat terminé"; +"success.message_format" = "Merci pour votre inscription. L'identifiant et le mot de passe de votre compte ont été envoyés à votre adresse e-mail %@"; +"success.redeem.title" = "Carte échangée avec succès"; +"success.redeem.message" = "Vous allez bientôt recevoir un e-mail contenant votre nom d'utilisateur et votre mot de passe.\n\nDétails de vos identifiants"; +"success.username.caption" = "Nom d'utilisateur"; +"success.password.caption" = "Mot de passe"; +"success.submit" = "Commencer"; + +"failure.vc_title" = "Échec de la connexion"; +"failure.title" = "La création du compte a échoué"; +"failure.message" = "Nous ne parvenons pas à créer un compte pour l'instant. Veuillez réessayer plus tard. \n\nRouvrir l'application engendrera une nouvelle tentative de création de compte."; +"failure.purchase.sandbox.message" = "L'abonnement sandbox sélectionné n'est pas disponible en production."; +"failure.redeem.invalid.title" = "Code PIN de la carte invalide"; +"failure.redeem.invalid.message" = "Il semblerait que le code PIN de la carte saisie soit invalide. Veuillez réessayer."; +"failure.redeem.claimed.title" = "Carte déjà utilisée"; +"failure.redeem.claimed.message" = "Il semblerait que cette carte soit déjà utilisée sur un autre compte. Vous pouvez essayer de saisir un code PIN différent."; +"failure.submit" = "REVENIR"; + +"unreachable.vc_title" = "Erreur"; +"unreachable.title" = "Oups !"; +"unreachable.message" = "Aucune connexion Internet trouvée. Veuillez confirmer que vous disposez d'une connexion Internet et cliquez de nouveau sur « Réessayer » ci-dessous.\n\nVous pourrez revenir dans l'application plus tard pour terminer le processus."; +"unreachable.submit" = "RÉESSAYER"; + +"purchase.uncredited.alert.message" = "Vous avez des transaction non créditées. Voulez-vous restaurer les détails de votre compte ?"; +"purchase.uncredited.alert.button.cancel" = "Annuler"; +"purchase.uncredited.alert.button.recover" = "Restaurer le compte"; + +"purchase.trials.intro" = "Démarrez votre essai gratuit de 7 jours"; +"purchase.trials.price.after" = "Ensuite %@"; +"purchase.trials.money.back" = "Garantie satisfait ou remboursé sur 30 jours"; +"purchase.trials.1year.protection" = "1 an de confidentialité et de protection de l'identité"; +"purchase.trials.anonymous" = "Surfez anonymement et masquez votre IP."; +"purchase.trials.devices" = "Prise en charge de 10 appareils en même temps"; +"purchase.trials.devices.description" = "Protégez-vous sur jusqu'à 10 appareils en même temps."; +"purchase.trials.region" = "Connectez-vous facilement à n'importe quelle région"; +"purchase.trials.servers" = "Plus de 3300 serveurs dans 32 pays"; +"purchase.trials.start" = "Commencer l'abonnement"; +"purchase.trials.all.plans" = "Voir tous les forfaits disponibles"; + +"purchase.subscribe.now" = "S'abonner maintenant"; + +// WALKTHROUGH + +"walkthrough.action.next" = "SUIVANT"; +"walkthrough.action.done" = "TERMINÉ"; +"walkthrough.action.skip" = "PASSER"; + +"walkthrough.page.1.title" = "Prend en charge 10 appareils en même temps"; +"walkthrough.page.1.description" = "Protégez-vous sur jusqu'à 10 appareils à la fois."; +"walkthrough.page.2.title" = "Connectez-vous facilement à n'importe quelle région"; +"walkthrough.page.2.description" = "Avec des serveurs partout dans le monde, vous êtes toujours sous protection."; +"walkthrough.page.3.title" = "Protégez-vous contre les publicités"; +"walkthrough.page.3.description" = "Activer notre bloqueur de contenu empêche les publicités de s'afficher dans Safari."; + +"share.data.buttons.accept" = "Accepter"; +"share.data.buttons.noThanks" = "Non, merci"; +"share.data.buttons.readMore" = "Lire plus"; +"share.data.text.title" = "Merci de nous aider à améliorer notre service"; +"share.data.text.description" = "Pour nous aider à garantir les performances de connexion de notre service, vous pouvez partager vos statistiques de connexion de manière anonyme avec nous. Ces rapports ne contiennent aucune information personnellement identifiable."; +"share.data.text.footer" = "Vous pouvez toujours contrôler cela à partir de vos paramètres."; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings new file mode 100644 index 000000000..fffdf519f --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Fermer"; +"global.ok" = "OK"; +"global.cancel" = "Annuler"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings new file mode 100644 index 000000000..623c17c3a --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Connectez-vous à votre compte"; +"login.username.placeholder" = "Nom d'utilisateur (p1234567)"; +"login.password.placeholder" = "Mot de passe"; +"login.submit" = "CONNEXION"; +"login.restore.button" = "Vous n'avez pas reçu les détails de votre compte ?"; +"login.error.title" = "Connexion"; +"login.error.validation" = "Vous devez saisir un nom d'utilisateur et un mot de passe."; +"login.error.unauthorized" = "Votre nom d'utilisateur ou mot de passe est incorrect."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Connectez-vous à l'aide du reçu d'achat"; +"login.magic.link.title" = "Connectez-vous à l'aide du lien e-mail magique"; +"login.magic.link.response" = "Veuillez vérifier vos e-mails pour trouver un lien de connexion."; +"login.magic.link.send" = "Envoyer un lien"; +"login.magic.link.invalid.email" = "E-mail invalide. Veuillez réessayer."; + +"purchase.title" = "Sélectionnez un forfait VPN"; +"purchase.subtitle" = "Garantie satisfait ou remboursé sur 30 jours"; +"purchase.email.placeholder" = "Adresse e-mail"; +"purchase.continue" = "Continuer"; +"purchase.login.footer" = "Vous avez déjà un compte ?"; +"purchase.login.button" = "Connectez-vous"; +"purchase.error.title" = "Acheter"; +"purchase.error.validation" = "Vous devez entrer une adresse e-mail."; +"purchase.error.connectivity.title" = "Échec de la connexion"; +"purchase.error.connectivity.description" = "Nous n'arrivons pas à joindre Private Internet Access. Cela peut être dû à une connexion Internet de faible qualité ou parce que notre service est bloqué dans votre pays."; +"purchase.confirm.form.email" = "Saisissez votre adresse e-mail"; +"purchase.confirm.plan" = "Vous achetez le forfait %@"; +"purchase.email.why" = "Nous avons besoin de votre e-mail pour envoyer votre nom d'utilisateur et votre mot de passe."; +"purchase.submit" = "Envoyer"; +"purchase.or" = "ou"; + +"upgrade.header" = "Bienvenue !"; +"upgrade.title" = "Afin d'utiliser Private Internet Access, vous devrez renouveler votre abonnement."; +"upgrade.renew.now" = "Renouveler maintenant"; + + + +"redeem.title" = "Échanger carte cadeau"; +"redeem.subtitle" = "Veuillez saisir ci-dessous votre adresse e-mail et le code PIN à %lu chiffres de votre carte cadeau ou carte d'essai."; +"redeem.email.placeholder" = "Adresse e-mail"; +"redeem.submit" = "ENVOYER"; +"redeem.error.title" = "Échanger"; +"redeem.error.code" = "Le code doit contenir %lu chiffres numériques."; +"redeem.error.allfields" = "Saisissez votre e-mail et le code PIN de votre carte."; +"redeem.accessibility.back" = "Retour"; +"redeem.giftcard.placeholder" = "Code PIN de la carte"; + +"plan.monthly.title" = "Mensuellement"; +"plan.yearly.title" = "Annuellement"; +"plan.yearly.detail_format" = "%@%@ par an"; +"plan.price_format" = "%@/mois"; +"plan.best_value" = "Économique"; +"plan.accessibility.per_month" = "par mois"; + +"restore.title" = "Restaurer l'achat non crédité"; +"restore.subtitle" = "Si vous avez acheté un forfait via cette application et n'avez pas reçu vos identifiants, il est possible de les renvoyer à partir d'ici. Cette action ne vous sera pas facturée."; +"restore.email.placeholder" = "Adresse e-mail"; +"restore.submit" = "CONFIRMER"; + +"iap.error.message.unavailable" = "Les serveurs Apple ne sont pas disponibles actuellement. Veuillez réessayer plus tard."; +"iap.error.title" = "Erreur"; + +"agreement.trials.title" = "Termes et conditions des essais gratuits"; +"agreement.trials.message" = "Le paiement sera débité de votre compte Apple ID au moment de la confirmation de l'achat. L'abonnement se renouvelle automatiquement à moins qu'il ne soit annulé au moins 24 heures avant la fin de la période en cours. Votre compte sera débité du renouvellement dans les 24 heures précédant la fin de la période actuelle. Vous pouvez gérer et annuler vos abonnements en accédant aux paramètres du compte sur l'App Store après l'achat.\n\nCertains abonnements payants peuvent offrir un essai gratuit avant de débiter votre méthode de paiement. Si vous décidez de vous désabonner d'un abonnement payant avant que nous commencions à débiter votre méthode de paiement, annulez l'abonnement au moins 24 heures avant la fin de l'essai.\n\nLes essais gratuits ne sont disponibles que pour les nouveaux utilisateurs et sont à notre entière discrétion et si vous tentez de vous inscrire pour un autre essai gratuit, vous serez immédiatement débité des frais d'abonnement standards.\n\nNous nous réservons le droit de révoquer votre essai gratuit à tout moment.\n\nToute partie non utilisée de votre période d'essai gratuit sera abandonnée au moment de l'achat d'un abonnement.\n\nL'inscription constitue l'acceptation de ces termes et conditions."; +"agreement.message" = "Après l'essai gratuit de 7 jour, cet abonnement est renouvelé automatiquement pour %@, sauf s'il est annulé au moins 24 heures avant la fin de la période d'essai. Votre compte de l'identifiant Apple sera facturé pour le renouvellement 24 heures avant la fin de la période d'essai. Vous pouvez gérer et annuler vos abonnements en accédant aux paramètres de votre compte de l'App Store après l'achat. L'offre de l'essai de 7 jours est limité à une seule offre d'essai de 7 jours par utilisateur. Toute partie non utilisée d'une période d'essai (le cas échéant) sera abandonnée lorsque l'utilisateur achète une abonnement. Tous les prix comprennent les taxes locales applicables.\n\nL'abonnement signifie que vous acceptez les $1 et la $2."; +"agreement.trials.yearly.plan" = "an"; +"agreement.trials.monthly.plan" = "mois"; + +"agreement.message.tos" = "Conditions d'utilisation"; +"agreement.message.privacy" = "Politique de confidentialité"; + +"getstarted.buttons.buyaccount" = "Acheter un compte"; + +"gdpr.collect.data.title" = "Informations personnelles que nous collectons"; +"gdpr.collect.data.description" = "Adresse e-mail dans le but de gérer le compte et de protéger des abus."; +"gdpr.usage.data.title" = "Utilisation des informations personnelles que nous collectons"; +"gdpr.usage.data.description" = "L'adresse e-mail est utilisée pour envoyer les informations d'abonnement, les confirmation de paiement, la correspondance avec le client, et les offres promotionnelles de Private Internet Access uniquement."; +"gdpr.accept.button.title" = "Accepter et continuer"; + +"update.account.email.error" = "Échec de la modification de l'e-mail du compte"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings new file mode 100644 index 000000000..b60ca1b4e --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Conferma registrazione"; +"in_progress.message" = "Conferma dell'acquisto col sistema in corso. Potrebbe impiegare qualche secondo. Attendi."; +"in_progress.redeem.message" = "Conferma del PIN della tua carta col sistema in corso. Potrebbe impiegare qualche secondo. Attendi."; + +"success.title" = "Acquisto completato"; +"success.message_format" = "Grazie per la registrazione. Ti abbiamo inviato nome utente e password del tuo account all'indirizzo e-mail %@"; +"success.redeem.title" = "Carta riscossa"; +"success.redeem.message" = "Riceverai un'email a breve con nome utente e password.\n\nI tuoi dati d'accesso"; +"success.username.caption" = "Nome utente"; +"success.password.caption" = "Password"; +"success.submit" = "Inizia"; + +"failure.vc_title" = "Registrazione non riuscita"; +"failure.title" = "Errore di creazione account"; +"failure.message" = "Impossibile creare un account in questo momento. Riprova più tardi. \n\nRiaprendo l'app si riproverà a creare un account."; +"failure.purchase.sandbox.message" = "L'abbonamento del sandbox selezionato on è disponibile in produzione."; +"failure.redeem.invalid.title" = "PIN della carta non valido"; +"failure.redeem.invalid.message" = "Hai inserito un PIN della carta non valido. Riprova."; +"failure.redeem.claimed.title" = "Carta già riscattata"; +"failure.redeem.claimed.message" = "Questa carta è già stata riscattata da un altro account. Prova a inserire un PIN diverso."; +"failure.submit" = "INDIETRO"; + +"unreachable.vc_title" = "Errore"; +"unreachable.title" = "Ops!"; +"unreachable.message" = "Nessuna connessione Internet trovata. Verifica la connessione Internet e premi Riprova di seguito.\n\nPuoi tornare all'app più tardi per terminare il processo."; +"unreachable.submit" = "RIPROVA"; + +"purchase.uncredited.alert.message" = "Hai transazioni non accreditate. Vuoi recuperare i dati del tuo account?"; +"purchase.uncredited.alert.button.cancel" = "Annulla"; +"purchase.uncredited.alert.button.recover" = "Recupera account"; + +"purchase.trials.intro" = "Inizia la tua prova gratuita da 7 giorni"; +"purchase.trials.price.after" = "Poi a %@"; +"purchase.trials.money.back" = "Garanzia di rimborso entro 30 giorni"; +"purchase.trials.1year.protection" = "1 anno di privacy e protezione d'indentità"; +"purchase.trials.anonymous" = "Sfoglia anonimamente e nascondi il tuo IP."; +"purchase.trials.devices" = "Supporta 10 dispositivi alla volta"; +"purchase.trials.devices.description" = "Proteggi un massimo di 10 dispositivi alla volta."; +"purchase.trials.region" = "Connettiti facilmente a qualsiasi regione"; +"purchase.trials.servers" = "Oltre 3300 server in 32 Paesi"; +"purchase.trials.start" = "Inizia abbonamento"; +"purchase.trials.all.plans" = "Vedi tutti i piani disponibili"; + +"purchase.subscribe.now" = "Iscriviti ora"; + +// WALKTHROUGH + +"walkthrough.action.next" = "AVANTI"; +"walkthrough.action.done" = "FATTO"; +"walkthrough.action.skip" = "SALTA"; + +"walkthrough.page.1.title" = "Supporta 10 dispositivi alla volta"; +"walkthrough.page.1.description" = "Proteggi te stesso su un massimo di 10 dispositivi alla volta."; +"walkthrough.page.2.title" = "Connettiti facilmente a qualsiasi regione"; +"walkthrough.page.2.description" = "Con server in tutto il mondo, sei sempre protetto."; +"walkthrough.page.3.title" = "Proteggiti dalle pubblicità"; +"walkthrough.page.3.description" = "Abilitando il nostro Blocco dei contenuti non visualizzerai la pubblicità mentre navighi con Safari."; + +"share.data.buttons.accept" = "Accetta"; +"share.data.buttons.noThanks" = "No, grazie"; +"share.data.buttons.readMore" = "Leggi di più"; +"share.data.text.title" = "Aiutaci a migliorare il tuo servizio"; +"share.data.text.description" = "Per aiutarci a garantire le prestazioni di connessione del nostro servizio, puoi condividere in modo anonimo le tue statistiche di connessione con noi. Questi rapporti non contengono informazioni d'identificazione personale."; +"share.data.text.footer" = "Puoi sempre controllare questa funzione dalle tue impostazioni"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/it.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/it.lproj/UI.strings new file mode 100644 index 000000000..fc2c6c196 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/it.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versione %@ (%@)"; +"global.close" = "Chiudi"; +"global.ok" = "OK"; +"global.cancel" = "Annulla"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings new file mode 100644 index 000000000..197265683 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Accedi al tuo account"; +"login.username.placeholder" = "Nome utente (p1234567)"; +"login.password.placeholder" = "Password"; +"login.submit" = "ACCEDI"; +"login.restore.button" = "Non hai ancora ricevuto i dettagli dell'account?"; +"login.error.title" = "Accedi"; +"login.error.validation" = "Devi inserire un nome utente e una password."; +"login.error.unauthorized" = "Nome utente o password non valida"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Accedi mediante ricevuta d'acquisto"; +"login.magic.link.title" = "Accedi tramite il link magico della mail"; +"login.magic.link.response" = "Controlla la tua mail per ottenere il link d'accesso."; +"login.magic.link.send" = "Invia link"; +"login.magic.link.invalid.email" = "Indirizzo email non valido. Riprova."; + +"purchase.title" = "Seleziona un piano VPN"; +"purchase.subtitle" = "Garanzia di rimborso entro 30 giorni"; +"purchase.email.placeholder" = "Indirizzo email"; +"purchase.continue" = "Continua"; +"purchase.login.footer" = "Possiedi già un account?"; +"purchase.login.button" = "Accedi"; +"purchase.error.title" = "Acquista"; +"purchase.error.validation" = "Devi indicare un indirizzo e-mail."; +"purchase.error.connectivity.title" = "Errore di connessione"; +"purchase.error.connectivity.description" = "Non siamo in grado di stabilire l'accesso a una rete Internet privata. Ciò potrebbe essere dovuto a una scarsa qualità della rete o a un blocco dei nostri servizi nel tuo paese."; +"purchase.confirm.form.email" = "Inserisci il tuo indirizzo email"; +"purchase.confirm.plan" = "Stai acquistando il piano %@"; +"purchase.email.why" = "Per inviarti nome utente e password, abbiamo bisogno del tuo indirizzo email."; +"purchase.submit" = "Invia"; +"purchase.or" = "o"; + +"upgrade.header" = "Bentornato!"; +"upgrade.title" = "Per usare Private Internet Access, devi rinnovare l'abbonamento."; +"upgrade.renew.now" = "Rinnova adesso"; + + + +"redeem.title" = "Riscatta la carta regalo"; +"redeem.subtitle" = "Digita qui sotto il tuo indirizzo email e le %lu cifre del PIN della carta regalo o carta di prova."; +"redeem.email.placeholder" = "Indirizzo email"; +"redeem.submit" = "INVIA"; +"redeem.error.title" = "Riscatta"; +"redeem.error.code" = "Il codice dev'essere di %lu cifre."; +"redeem.error.allfields" = "Digita il tuo indirizzo email e PIN della carta."; +"redeem.accessibility.back" = "Indietro"; +"redeem.giftcard.placeholder" = "PIN carta regalo"; + +"plan.monthly.title" = "Mensile"; +"plan.yearly.title" = "Annuale"; +"plan.yearly.detail_format" = "%@%@ all'anno"; +"plan.price_format" = "%@ al mese"; +"plan.best_value" = "Valore migliore"; +"plan.accessibility.per_month" = "al mese"; + +"restore.title" = "Ripristina acquisto non accreditato"; +"restore.subtitle" = "Se hai acquistato un piano mediante questa app ma non hai ricevuto le tue credenziali, puoi inviarle nuovamente da qui.\nNon verrà effettuato alcun addebito durante la procedura."; +"restore.email.placeholder" = "Indirizzo email"; +"restore.submit" = "CONFERMA"; + +"iap.error.message.unavailable" = "Server Apple attualmente non disponibili. Riprova più tardi."; +"iap.error.title" = "Errore"; + +"agreement.trials.title" = "Termini e condizioni della prova gratuita"; +"agreement.trials.message" = "Il pagamento verrà addebitato sul tuo account ID Apple alla conferma dell'acquisto. L'abbonamento si rinnova automaticamente a meno che non venga annullato entro 24 ore dalla fine del periodo attuale. Il tuo account verrà addebitato per il rinnovo entro 24 ore dalla fine del periodo attuale. Puoi gestire e cancellare i tuoi abbonamenti dalle impostazioni dell'account sull'App Store dopo l'acquisto.\n\nAlcuni abbonamenti a pagamento possono offrire una prova gratuita prima di addebitare il metodo di pagamento. Se decidi di annullare l'iscrizione a un abbonamento a pagamento prima dell'addebito, dovrai annullarla entro 24 ore dalla scadenza della prova gratuita.\n\nLe prove gratuite sono disponibili solo per i nuovi utenti e sono a nostra esclusiva discrezione. In caso di registrazione per ottenere una prova gratuita aggiuntiva, l'addebito dell'importo standard dell'abbonamento verrà effettuato immediatamente.\n\nCi riserviamo il diritto di revocare la prova gratuita in qualsiasi momento.\n\nQualsiasi parte inutilizzata del periodo di prova gratuito andrà persa al momento dell'acquisto di un abbonamento.\n\nLa registrazione implica l'accettazione dei presenti termini e condizioni."; +"agreement.message" = "Dopo 7 giorni di prova gratuita, l'abbonamento si rinnova automaticamente per % @ a meno che non venga annullato entro 24 ore dalla fine del periodo di prova. Il tuo account ID Apple verrà addebitato per il rinnovo entro 24 ore dalla fine del periodo di prova. Puoi gestire e cancellare i tuoi abbonamenti andando sulle impostazioni del tuo account App Store dopo l'acquisto. L'offerta di prova di 7 giorni è limitata a un'unica offerta da 7 giorni per utente. Ogni parte inutilizzata di un periodo di prova gratuito, se offerto, andrà perduta quando l'utente acquista un abbonamento. Tutti i prezzi includono le tasse locali applicabili.\n\nLa registrazione implica l'accettazione di $1 e $2."; +"agreement.trials.yearly.plan" = "anno"; +"agreement.trials.monthly.plan" = "mese"; + +"agreement.message.tos" = "Termini di servizio"; +"agreement.message.privacy" = "Informativa sulla Privacy"; + +"getstarted.buttons.buyaccount" = "Acquista account"; + +"gdpr.collect.data.title" = "Dati personali da noi raccolti"; +"gdpr.collect.data.description" = "Indirizzo email ai fini di gestione dell'account e della protezione dall'uso improprio."; +"gdpr.usage.data.title" = "Usi delle informazioni personali da noi richieste"; +"gdpr.usage.data.description" = "L'indirizzo email viene utilizzato solo per inviare informazioni sull'abbonamento, conferme di pagamento, corrispondenza col cliente e offerte promozionali di Private Internet Access."; +"gdpr.accept.button.title" = "Accetta e continua"; + +"update.account.email.error" = "Modifica email account non riuscita"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings new file mode 100644 index 000000000..886508935 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "サインアップを確定"; +"in_progress.message" = "システムがご購入を確定しています。しばらく時間がかかることがありますので、そのままお待ちください。"; +"in_progress.redeem.message" = "システムがご購入を確定しています。しばらく時間がかかることがありますので、そのままお待ちください。"; + +"success.title" = "購入完了"; +"success.message_format" = "サインアップありがとうございます。アカウントのユーザー名とパスワードをお客様のメールアドレス(%@)に送信いたしました。"; +"success.redeem.title" = "カードの引き換えが完了しました"; +"success.redeem.message" = "ユーザーネームとパスワードを記載したメールがまもなく届きます。\n\nお客様のログイン詳細"; +"success.username.caption" = "ユーザー名"; +"success.password.caption" = "パスワード"; +"success.submit" = "始める"; + +"failure.vc_title" = "サインアップできませんでした"; +"failure.title" = "アカウントの作成に失敗しました"; +"failure.message" = "ただ今アカウントを作成できません。後ほどもう一度お試しください。\n\nアプリを再起動すると、アカウント作成が再試行されます。"; +"failure.purchase.sandbox.message" = "選択されたサンドボックスのサブスクリプションは生産中のため利用できません。"; +"failure.redeem.invalid.title" = "無効なカードPIN"; +"failure.redeem.invalid.message" = "無効なカードPINを入力したようです。もう一度お試しください。"; +"failure.redeem.claimed.title" = "すでに獲得されたカードです"; +"failure.redeem.claimed.message" = "このカードは、すでに別のアカウントが獲得したようです。別のPINを入力してください。"; +"failure.submit" = "戻る"; + +"unreachable.vc_title" = "エラー"; +"unreachable.title" = "おっと!"; +"unreachable.message" = "インターネット接続が見つかりません。インターネットに接続していることを確認してから下の再試行をタップしてください。\n\n後ほどアプリでこのプロセスを完了することができます。"; +"unreachable.submit" = "再試行"; + +"purchase.uncredited.alert.message" = "反映されていない取引があります。アカウントの詳細を回復しますか?"; +"purchase.uncredited.alert.button.cancel" = "キャンセル"; +"purchase.uncredited.alert.button.recover" = "アカウントを回復"; + +"purchase.trials.intro" = "7日間無料トライアルを開始"; +"purchase.trials.price.after" = "以後%@"; +"purchase.trials.money.back" = "30日間返金保証"; +"purchase.trials.1year.protection" = "1年間のプライバシーおよび個人情報の保護"; +"purchase.trials.anonymous" = "ウェブの匿名利用でIPを非表示にします。"; +"purchase.trials.devices" = "一度に10台の端末をサポート"; +"purchase.trials.devices.description" = "一度に最大10台の端末を保護して自分を守ることができます。"; +"purchase.trials.region" = "すべての地域に簡単に接続"; +"purchase.trials.servers" = "32か国の3300以上のサーバー"; +"purchase.trials.start" = "サブスクリプションを開始"; +"purchase.trials.all.plans" = "利用可能なプランをすべて見る"; + +"purchase.subscribe.now" = "今すぐ定期購読を購入"; + +// WALKTHROUGH + +"walkthrough.action.next" = "次へ"; +"walkthrough.action.done" = "完了"; +"walkthrough.action.skip" = "スキップ"; + +"walkthrough.page.1.title" = "一度に10台の端末をサポート"; +"walkthrough.page.1.description" = "一度に最大10台の端末を保護して自分を守ることができます。"; +"walkthrough.page.2.title" = "あらゆる地域に簡単に接続"; +"walkthrough.page.2.description" = "世界中にサーバがあるので、常に保護された状態でいることができます。"; +"walkthrough.page.3.title" = "広告から自分を守りましょう"; +"walkthrough.page.3.description" = "コンテンツブロッカーを有効にすると、Safariで広告表示をブロックできます。"; + +"share.data.buttons.accept" = "同意する"; +"share.data.buttons.noThanks" = "いいえ、結構です"; +"share.data.buttons.readMore" = "もっと読む"; +"share.data.text.title" = "弊社のサービス改善にご協力ください"; +"share.data.text.description" = "弊社のサービスの接続パフォーマンス確保にご協力いただくには、接続データを匿名で弊社と共有してください。これらのレポートには、個人を特定できる情報は含まれません。"; +"share.data.text.footer" = "これは、設定からいつでもコントロール可能です"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings new file mode 100644 index 000000000..1751458e6 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "バージョン%@ (%@)"; +"global.close" = "閉じる"; +"global.ok" = "OK"; +"global.cancel" = "キャンセル"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings new file mode 100644 index 000000000..98aa77a8f --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "アカウントにサインイン"; +"login.username.placeholder" = "ユーザー名 (p1234567)"; +"login.password.placeholder" = "パスワード"; +"login.submit" = "ログイン"; +"login.restore.button" = "アカウント詳細を受信しませんでしたか?"; +"login.error.title" = "ログイン"; +"login.error.validation" = "ユーザー名とパスワードを入力してください。"; +"login.error.unauthorized" = "ユーザー名またはパスワードが間違っています。"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "購入領収書を使用してログイン"; +"login.magic.link.title" = "魔法のメールリンクを使用してログイン"; +"login.magic.link.response" = "ログインリンクについては、メールを確認してください。"; +"login.magic.link.send" = "リンクを送信"; +"login.magic.link.invalid.email" = "無効なメールアドレス。もう一度お試しください。"; + +"purchase.title" = "VPNプランを選択"; +"purchase.subtitle" = "30日間返金保証"; +"purchase.email.placeholder" = "メールアドレス"; +"purchase.continue" = "続行"; +"purchase.login.footer" = "既にアカウントをお持ちですか?"; +"purchase.login.button" = "サインイン"; +"purchase.error.title" = "購入"; +"purchase.error.validation" = "必ずメールアドレスを入力してください。"; +"purchase.error.connectivity.title" = "接続エラー"; +"purchase.error.connectivity.description" = "Private Internet Accessに接続できませんでした。インターネットの接続が不安定、もしくはお住まいの国で当社サービスがブロックされている可能性があります。"; +"purchase.confirm.form.email" = "メールアドレスを入力してください"; +"purchase.confirm.plan" = "お客様は%@プランを購入しようとしています"; +"purchase.email.why" = "ユーザー名とパスワードを送信するためのメールアドレスを入力してください。"; +"purchase.submit" = "送信"; +"purchase.or" = "または"; + +"upgrade.header" = "お帰りなさい!"; +"upgrade.title" = "Private Internet Accessのご利用を継続するには、サブスクリプションを更新する必要があります。"; +"upgrade.renew.now" = "今すぐ更新"; + + + +"redeem.title" = "ギフトカード引換え"; +"redeem.subtitle" = "メールアドレスと、以下のギフトカードまたはトライアルカードの%lu桁のPINを入力してください。"; +"redeem.email.placeholder" = "メールアドレス"; +"redeem.submit" = "送信"; +"redeem.error.title" = "引換え"; +"redeem.error.code" = "コードは%lu桁でなければなりません。"; +"redeem.error.allfields" = "メールアドレスとカードのPINを入力してください。"; +"redeem.accessibility.back" = "戻る"; +"redeem.giftcard.placeholder" = "ギフトカードのPIN"; + +"plan.monthly.title" = "月間"; +"plan.yearly.title" = "年間"; +"plan.yearly.detail_format" = "年間%@%@"; +"plan.price_format" = "%@/月"; +"plan.best_value" = "最もお得"; +"plan.accessibility.per_month" = "月々"; + +"restore.title" = "追加されていない更新を復元"; +"restore.subtitle" = "このアプリでプランを購入した後、認証情報を受け取っていない方は、こちらから認証情報を再度送信することができます。この処理の実行中、課金は発生しません。"; +"restore.email.placeholder" = "メールアドレス"; +"restore.submit" = "確定"; + +"iap.error.message.unavailable" = "Appleサーバーが現在ご利用いただけません。後でもう一度お試しください。"; +"iap.error.title" = "エラー"; + +"agreement.trials.title" = "無料トライアル利用規約"; +"agreement.trials.message" = "ご購入確定時にお使いのApple IDアカウント支払額が請求されます。サブスクリプションは現在の期間が終了する24時間前までにキャンセルされない限り自動的に更新されます。更新料は現在の期間終了前の24時間以内にお使いのアカウントに請求されます。サブスクリプションはご購入後にApp Storeのアカウント設定からいつでも管理およびキャンセルすることができます。\n\n一部の有料サブスクリプションでは、ご希望の支払方法による請求が実施される前に無料トライアルが提供されている場合があります。ご選択の支払方法による請求が実施される前に有料サブスクリプションの解約をする場合は、無料トライアルが終了する24時間前までにサブスクリプションをキャンセルしてください。\n\n無料トライアルをご利用いただけるのは新規ユーザーのみとなり、無料トライアルを使用する目的で新たに追加のアカウントをサインアップした場合、弊社の裁量によって、通常のサブスクリプション料金が即時に請求されます。\n\n弊社は無料トライアル期間をいつでも無効にする権利を保持します。\n\nサブスクリプションご購入後、未使用分の無料トライアル期間は無効となります。\n\nサインアップすることで、$1と$2に同意したことになります。"; +"agreement.message" = "トライアル期間終了の少なくとも24時間前にキャンセルされない限り、7日間の無料トライアル後、この定期購読は自動的に%@で更新されます。更新料は、トライアル期間終了前の24時間以内にご利用のApple IDアカウントに請求されます。定期購読は、定期購読購入後にApp Storeアカウント設定から管理およびキャンセルすることができます。7日間のトライアルオファーは、ユーザー1人あたり1回の7日間トライアルに限られています。無料トライアルを利用した場合、無料トライアル期間の未使用分は、ユーザーが定期購読を購入した時点で無効となります。すべての料金には、適用可能な場合現地の消費税が含まれます。\n\nサインアップすることにより、$1および$2に同意したことになります。"; +"agreement.trials.yearly.plan" = "年"; +"agreement.trials.monthly.plan" = "月"; + +"agreement.message.tos" = "利用規約"; +"agreement.message.privacy" = "プライバシーポリシー"; + +"getstarted.buttons.buyaccount" = "アカウントを購入する"; + +"gdpr.collect.data.title" = "弊社が収集する個人情報"; +"gdpr.collect.data.description" = "メールアドレスは、アカウント管理、および乱用からの保護を目的とします。"; +"gdpr.usage.data.title" = "弊社により収集される個人情報の使用"; +"gdpr.usage.data.description" = "メールアドレスはサブスクリプション情報、お支払確認、お客様とのやり取り、およびPrivate Internet Accessのプロモーションオファーを送信するためにのみ使用されます。"; +"gdpr.accept.button.title" = "同意して続行する"; + +"update.account.email.error" = "アカウントのメールを変更できませんでした"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings new file mode 100644 index 000000000..cfd62453f --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "회원 가입 확인"; +"in_progress.message" = "저희 시스템에서 고객님의 구매를 확인하고 있습니다. 약간 시간이 소요될 수 있으므로 양해 부탁드립니다."; +"in_progress.redeem.message" = "저희 시스템에서 고객님의 카드 PIN을 확인하고 있습니다. 약간 시간이 소요될 수 있으므로 양해 부탁드립니다."; + +"success.title" = "구매 완료"; +"success.message_format" = "회원으로 가입해 주셔서 감사합니다. 계정 사용자명과 비밀번호를 귀하의 이메일 주소(%@)로 발송했습니다."; +"success.redeem.title" = "카드 사용 성공"; +"success.redeem.message" = "사용자 이름 및 비밀번호가 담긴 이메일을 곧 보내드리겠습니다.\n\n귀하의 로그인 정보"; +"success.username.caption" = "사용자 이름"; +"success.password.caption" = "비밀번호"; +"success.submit" = "시작하기"; + +"failure.vc_title" = "회원 가입 실패"; +"failure.title" = "계정 생성 실패"; +"failure.message" = "지금은 계정을 생성할 수 없습니다. 나중에 다시 시도해주십시오.\n\n 앱을 다시 열면 계정 생성을 다시 시도합니다."; +"failure.purchase.sandbox.message" = "선택하신 샌드박스 구독은 생산에 사용할 수 없습니다."; +"failure.redeem.invalid.title" = "유효하지 않은 카드 PIN"; +"failure.redeem.invalid.message" = "유효하지 않은 카드 PIN을 입력한 것 같습니다. 다시 시도하세요."; +"failure.redeem.claimed.title" = "이미 청구한 카드"; +"failure.redeem.claimed.message" = "이 카드는 이미 다른 계정에서 청구한 것 같습니다. 다른 PIN을 입력해 보세요."; +"failure.submit" = "뒤로"; + +"unreachable.vc_title" = "오류"; +"unreachable.title" = "앗!"; +"unreachable.message" = "인터넷에 연결되지 않았습니다. 인터넷에 연결되어 있는지 확인하신 후 아래에서 다시 시도를 누르십시오.\n\n나중에 앱에 다시 돌아와서 이 과정을 완료할 수 있습니다."; +"unreachable.submit" = "다시 시도"; + +"purchase.uncredited.alert.message" = "처리되지 않은 거래가 있습니다. 계정 정보를 복구하시겠습니까?"; +"purchase.uncredited.alert.button.cancel" = "취소"; +"purchase.uncredited.alert.button.recover" = "계정 복구"; + +"purchase.trials.intro" = "7일 무료 체험 시작"; +"purchase.trials.price.after" = "그 후 %@"; +"purchase.trials.money.back" = "30일 이내 환불 보장"; +"purchase.trials.1year.protection" = "1년간 프라이버시 및 신원 보호"; +"purchase.trials.anonymous" = "익명으로 검색하고 IP를 숨기세요."; +"purchase.trials.devices" = "동시에 10대의 장치 지원"; +"purchase.trials.devices.description" = "한 번에 최대 10대의 장치에서 보호를 받으세요."; +"purchase.trials.region" = "모든 지역에 쉽게 연결"; +"purchase.trials.servers" = "32개국 3300개 이상의 서버"; +"purchase.trials.start" = "구독 시작"; +"purchase.trials.all.plans" = "이용 가능한 모든 플랜 보기"; + +"purchase.subscribe.now" = "지금 구독"; + +// WALKTHROUGH + +"walkthrough.action.next" = "다음"; +"walkthrough.action.done" = "완료"; +"walkthrough.action.skip" = "건너뛰기"; + +"walkthrough.page.1.title" = "한 번의 10대의 장치 지원"; +"walkthrough.page.1.description" = "한 번에 최대 10대의 장치에서 보호를 받으세요."; +"walkthrough.page.2.title" = "모든 지역에 쉽게 연결"; +"walkthrough.page.2.description" = "전 세계에 있는 서버를 통해 언제나 보호를 받습니다."; +"walkthrough.page.3.title" = "광고로부터 보호"; +"walkthrough.page.3.description" = "Content Blocker를 활성화하면 Safari에서 광고가 표시되지 않습니다."; + +"share.data.buttons.accept" = "수락"; +"share.data.buttons.noThanks" = "아니요"; +"share.data.buttons.readMore" = "자세히 보기"; +"share.data.text.title" = "저희 서비스를 개선하도록 도와 주세요"; +"share.data.text.description" = "연결 상태를 저희와 익명으로 공유해 주시면 저희 서비스의 연결 성능을 개선하는 데 도움이 됩니다. 이 보고서에는 개인 식별 정보가 포함되지 않습니다."; +"share.data.text.footer" = "언제든지 설정에서 이 옵션을 관리할 수 있습니다."; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings new file mode 100644 index 000000000..1c9f1e509 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "버전 %@ (%@)"; +"global.close" = "닫기"; +"global.ok" = "확인"; +"global.cancel" = "취소"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings new file mode 100644 index 000000000..2d29b5f83 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "계정에 로그인"; +"login.username.placeholder" = "사용자 이름 (p1234567)"; +"login.password.placeholder" = "비밀번호"; +"login.submit" = "로그인"; +"login.restore.button" = "계정 정보를 받지 못하셨습니까?"; +"login.error.title" = "로그인"; +"login.error.validation" = "사용자 이름과 비밀번호를 입력하셔야 합니다."; +"login.error.unauthorized" = "사용자명 또는 비밀번호가 틀립니다."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "구매 영수증을 사용해 로그인"; +"login.magic.link.title" = "이메일 링크를 사용해 간편하게 로그인"; +"login.magic.link.response" = "로그인 링크가 담긴 이메일을 확인하세요."; +"login.magic.link.send" = "링크 보내기"; +"login.magic.link.invalid.email" = "이메일이 유효하지 않음. 다시 시도하세요."; + +"purchase.title" = "VPN 플랜 선택"; +"purchase.subtitle" = "30일 이내 환불 보장"; +"purchase.email.placeholder" = "이메일 주소"; +"purchase.continue" = "계속"; +"purchase.login.footer" = "이미 계정이 있으세요?"; +"purchase.login.button" = "로그인"; +"purchase.error.title" = "구매"; +"purchase.error.validation" = "이메일 주소를 입력하셔야 합니다."; +"purchase.error.connectivity.title" = "연결 실패"; +"purchase.error.connectivity.description" = "Private Internet Access에 접속할 수 없습니다. 인터넷 연결 상태가 좋지 않거나 귀하의 국가에서 당사의 서비스가 차단된 것 같습니다."; +"purchase.confirm.form.email" = "이메일 주소를 입력하세요"; +"purchase.confirm.plan" = "%@ 플랜을 구매합니다"; +"purchase.email.why" = "사용자 이름 및 비밀번호를 보내 드리면 고객님의 이메일 주소가 필요합니다."; +"purchase.submit" = "제출"; +"purchase.or" = "또는"; + +"upgrade.header" = "다시 오신 걸 환영합니다!"; +"upgrade.title" = "Private Internet Access를 사용하려면 구독을 갱신하셔야 합니다."; +"upgrade.renew.now" = "지금 갱신"; + + + +"redeem.title" = "기프트 카드 청구"; +"redeem.subtitle" = "기프트 카드 또는 체험 카드의 %lu자리 PIN과 이메일 주소를 입력하세요."; +"redeem.email.placeholder" = "이메일 주소"; +"redeem.submit" = "제출"; +"redeem.error.title" = "청구"; +"redeem.error.code" = "코드는 %lu자리 숫자여야 합니다."; +"redeem.error.allfields" = "이메일 및 카드 PIN을 입력하세요."; +"redeem.accessibility.back" = "뒤로"; +"redeem.giftcard.placeholder" = "기프트 카드 PIN"; + +"plan.monthly.title" = "월간"; +"plan.yearly.title" = "연간"; +"plan.yearly.detail_format" = "매년 %@%@"; +"plan.price_format" = "%@/월"; +"plan.best_value" = "최저가"; +"plan.accessibility.per_month" = "매월"; + +"restore.title" = "인정되지 않은 구매 항목 복원"; +"restore.subtitle" = "이 앱을 통해 요금 플랜을 구매하셨는데 자격 증명 정보를 받지 못하신 경우 이곳에서 다시 보내실 수 있습니다. 이 과정 중 요금이 부과되지 않습니다.\n"; +"restore.email.placeholder" = "이메일 주소"; +"restore.submit" = "확인"; + +"iap.error.message.unavailable" = "현재 Apple 서버를 이용할 수 없습니다. 나중에 다시 시도해주십시오."; +"iap.error.title" = "오류"; + +"agreement.trials.title" = "무료 체험 계약 조건"; +"agreement.trials.message" = "구매 확인 시 사용자의 Apple ID 계정으로 요금이 청구됩니다. 현재 기간이 종료하기 24시간 전에 취소하지 않으면 구독은 자동으로 갱신됩니다. 현재 기간이 종료하기 전 24시간 이내에 갱신 요금이 계정으로 청구됩니다. 구매 후 App Store의 계정 설정에서 구독을 관리하고 취소할 수 있습니다.\n\n일부 유료 구독은 사용자의 결제 수단으로 청구하기 전에 무료 체험을 제공할 수 있습니다. 결제 수단으로 청구가 시작되기 전에 유료 구독을 취소하려면, 무료 체험 기간이 종료하기 24시간 전에 구독을 취소하십시오.\n\n무료 체험은 신규 사용자만 이용할 수 있으며, 당사의 단독 재량으로 제공됩니다. 무료 체험을 추가로 이용하기 위해 가입한 경우 표준 구독 요금이 즉시 청구됩니다.\n\n당사는 언제든지 무료 체험을 철회할 권리를 보유합니다.\n\n구독 구매 시 무료 체험 기간의 미사용분은 소멸됩니다.\n\n가입 시 본 계약 조건에 동의하신 것으로 간주됩니다."; +"agreement.message" = "체험 기간이 종료하기 24시간 전에 구독을 취소하지 않으면, 7일 무료 체험 후 이 구독은 %@에 자동으로 갱신됩니다. 체험 기간이 종료하기 전 24시간 이내에 사용자의 Apple ID로 갱신 요금이 청구됩니다. 구매 후 App Store 계정으로 이동하여 구독을 관리하고 취소할 수 있습니다. 7일 체험 혜택은 사용자당 한 번으로 제한됩니다. 사용자가 구독을 구매할 경우 무료 체험 기간의 미사용분은 소멸됩니다. 모든 가격에는 현지에서 적용되는 판매세가 포함됩니다.\n\n가입 시 $1 및 $2에 동의하신 것으로 간주됩니다."; +"agreement.trials.yearly.plan" = "년"; +"agreement.trials.monthly.plan" = "개월"; + +"agreement.message.tos" = "서비스 약관"; +"agreement.message.privacy" = "개인정보 취급방침"; + +"getstarted.buttons.buyaccount" = "계정 구입"; + +"gdpr.collect.data.title" = "당사가 수집하는 개인 정보"; +"gdpr.collect.data.description" = "계정 관리 및 악용 방지를 위한 이메일 주소."; +"gdpr.usage.data.title" = "수집된 개인 정보의 사용"; +"gdpr.usage.data.description" = "이메일 주소는 구독 정보, 결제 확인, 고객 공지 사항 및 Private Internet Access 프로모션 정보를 보내는 데에만 사용됩니다."; +"gdpr.accept.button.title" = "동의 및 계속"; + +"update.account.email.error" = "계정 이메일을 수정하지 못했습니다"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings new file mode 100644 index 000000000..300d513ed --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Bekrefter registrering"; +"in_progress.message" = "Vi bekrefter kjøpet i systemet vårt. Dette kan ta litt tid."; +"in_progress.redeem.message" = "Vi bekrefter kort-PIN-en din i systemet vårt. Det kan ta et øyeblikk, så vennligst vent."; + +"success.title" = "Kjøp fullført"; +"success.message_format" = "Takk for at du registrerte deg. Vi har sendt deg kontonavnet og passordet ditt til e-postadressen din %@"; +"success.redeem.title" = "Kortet har blitt innløst"; +"success.redeem.message" = "Du mottar en e-post med brukernavn og passord.\n\nPåloggingsinformasjonen din"; +"success.username.caption" = "Brukernavn"; +"success.password.caption" = "Passord"; +"success.submit" = "Komme i gang"; + +"failure.vc_title" = "Registrering mislyktes"; +"failure.title" = "Kunne ikke opprette kontoen"; +"failure.message" = "Vi kunne ikke opprette en konto nå. Prøv på nytt senere.\n\nNår du åpner appen igjen, vil den prøve å opprette kontoen på nytt."; +"failure.purchase.sandbox.message" = "Det valgte sandboksabonnementet er ikke tilgjengelig i produksjon."; +"failure.redeem.invalid.title" = "Ugyldig kort-PIN"; +"failure.redeem.invalid.message" = "Ser ut til at du brukte en ugyldig kort-PIN. Prøv igjen"; +"failure.redeem.claimed.title" = "Kortet er allerede brukt"; +"failure.redeem.claimed.message" = "Ser ut til at kortet allerede er brukt av en annen konto. Du kan prøve med en annen PIN."; +"failure.submit" = "GÅ TILBAKE"; + +"unreachable.vc_title" = "Feil"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Ingen internettilkobling. Bekreft at du er koblet til Internett og trykk på Prøv igjen nedenfor.\n\nDu kan komme tilbake til appen senere for å fullføre prosessen."; +"unreachable.submit" = "PRØV PÅ NYTT"; + +"purchase.uncredited.alert.message" = "Du har ikke krediterte transaksjoner. Vil du gjenopprette kontoinformasjonen din?"; +"purchase.uncredited.alert.button.cancel" = "Abryt"; +"purchase.uncredited.alert.button.recover" = "Gjenopprett konto"; + +"purchase.trials.intro" = "Start din gratis 7-dagers prøveperiode"; +"purchase.trials.price.after" = "Deretter %@"; +"purchase.trials.money.back" = "30 dagers pengene-tilbake-garanti"; +"purchase.trials.1year.protection" = "Et års personverns- og identitetsbeskyttelse"; +"purchase.trials.anonymous" = "Surf anonymt og skjul IP-adressen din."; +"purchase.trials.devices" = "Støtter ti enheter om gangen"; +"purchase.trials.devices.description" = "Beskytt deg på opptil ti enheter samtidig."; +"purchase.trials.region" = "Koble til hvilken som helst region på en enkel måte"; +"purchase.trials.servers" = "Over 3300 servere i 32 land"; +"purchase.trials.start" = "Start abonnementet"; +"purchase.trials.all.plans" = "Vis alle tilgjengelige abonnement"; + +"purchase.subscribe.now" = "Abonner nå"; + +// WALKTHROUGH + +"walkthrough.action.next" = "NESTE"; +"walkthrough.action.done" = "FERDIG"; +"walkthrough.action.skip" = "HOPP OVER"; + +"walkthrough.page.1.title" = "Støtter ti enheter samtidig"; +"walkthrough.page.1.description" = "Beskytt deg på opptil ti enheter samtidig."; +"walkthrough.page.2.title" = "Koble til hvilken som helst region på en enkel måte"; +"walkthrough.page.2.description" = "Med serverer rundt om i hele verden, er du alltid beskyttet."; +"walkthrough.page.3.title" = "Beskytt deg selv mot reklame"; +"walkthrough.page.3.description" = "Aktivering av innholdsblokkereren sikrer at reklame ikke blir vist når du bruker Safari."; + +"share.data.buttons.accept" = "Godta"; +"share.data.buttons.noThanks" = "Nei takk"; +"share.data.buttons.readMore" = "Les mer"; +"share.data.text.title" = "Hjelp oss med å forbedre tjenesten vår"; +"share.data.text.description" = "For å hjelpe oss med å sikre tjenestens tilkoblingsytelse, kan du anonymt dele tilkoblingsstatistikken din med oss. Disse rapportene inkluderer informasjon som ikke er personlig identifiserbar."; +"share.data.text.footer" = "Du kan kontrollere dette fra innstillingene dine"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings new file mode 100644 index 000000000..5ccb0d7dc --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versjon %@ (%@)"; +"global.close" = "Lukk"; +"global.ok" = "OK"; +"global.cancel" = "Avbryt"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings new file mode 100644 index 000000000..80faed974 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Logg inn på kontoen din"; +"login.username.placeholder" = "Brukernavn (p1234567)"; +"login.password.placeholder" = "Passord"; +"login.submit" = "LOGG INN"; +"login.restore.button" = "Har du ikke fått kontodetaljene?"; +"login.error.title" = "Logg på"; +"login.error.validation" = "Du må oppgi et brukernavn og passord."; +"login.error.unauthorized" = "Brukernavnet eller passordet ditt er feil."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Logg på med kjøpsbevis"; +"login.magic.link.title" = "Pålogging med magisk e-postkobling"; +"login.magic.link.response" = "Sjekk e-posten din for å finne påloggingskoblingen."; +"login.magic.link.send" = "Send kobling"; +"login.magic.link.invalid.email" = "Ugyldig e-post. Prøv igjen."; + +"purchase.title" = "Velg et VPN-abonnement"; +"purchase.subtitle" = "30 dagers pengene-tilbake-garanti"; +"purchase.email.placeholder" = "E-postadresse"; +"purchase.continue" = "Fortsett"; +"purchase.login.footer" = "Har du allerede en konto?"; +"purchase.login.button" = "Logg inn"; +"purchase.error.title" = "Kjøp"; +"purchase.error.validation" = "Du må angi en e-postadresse."; +"purchase.error.connectivity.title" = "Tilkoblingsfeil"; +"purchase.error.connectivity.description" = "Vi kunne ikke nå Private Internet Access. Dette kan skyldes dårlig Internett eller at tjenesten vår er blokkert i landet ditt."; +"purchase.confirm.form.email" = "Angi e-postadressen din"; +"purchase.confirm.plan" = "Du kjøper %@-abonnementet"; +"purchase.email.why" = "Vi trenger e-posten din for å sende deg brukernavnet og passordet ditt."; +"purchase.submit" = "Send inn"; +"purchase.or" = "eller"; + +"upgrade.header" = "Velkommen tilbake!"; +"upgrade.title" = "For å bruke en privat internettilgang, må du fornye abonnementet ditt."; +"upgrade.renew.now" = "Forny nå"; + + + +"redeem.title" = "Løs inn gavekort"; +"redeem.subtitle" = "Angi e-postadressen og den %lu-sifrede PIN-koden fra gavekortet eller prøvekortet nedenfor."; +"redeem.email.placeholder" = "E-postadresse"; +"redeem.submit" = "SEND"; +"redeem.error.title" = "Løs inn"; +"redeem.error.code" = "Koden må bestå av %lu siffer."; +"redeem.error.allfields" = "Angi e-postadressen din og kortet PIN-kode."; +"redeem.accessibility.back" = "Tilbake"; +"redeem.giftcard.placeholder" = "PIN-kode for gavekort"; + +"plan.monthly.title" = "Månedlig"; +"plan.yearly.title" = "Årlig"; +"plan.yearly.detail_format" = "%@%@ per år"; +"plan.price_format" = "%@/mnd"; +"plan.best_value" = "Mest for pengene"; +"plan.accessibility.per_month" = "per måned"; + +"restore.title" = "Gjenopprett ukreditert kjøp"; +"restore.subtitle" = "Hvis du har kjøpt en plan via appen og ikke har mottatt opplysningene dine, kan du sende dem på nytt herfra.\nDu belastes ikke under denne prosessen."; +"restore.email.placeholder" = "E-postadresse"; +"restore.submit" = "BEKREFT"; + +"iap.error.message.unavailable" = "Apple-serverne er for øyeblikket ikke tilgjengelige. Prøv igjen senere."; +"iap.error.title" = "Feil"; + +"agreement.trials.title" = "Vilkår og betingelser for gratis prøveperiode"; +"agreement.trials.message" = "Betalingen belastes Apple ID-kontoen din når du bekrefter kjøpet. Abonnementet fornyes automatisk med mindre det kanselleres minst 24 timer før slutten av den inneværende perioden. Kontoen blir belastet for fornyelse innen 24 timer før slutten av den inneværende perioden. Du kan administrere og kansellere abonnementene dine ved besøke kontoinnstillingene på App Store etter kjøpet.\n\nEnkelte betalte abonnementer kan tilby en gratis prøveperiode før det belaster betalingsmetoden din. Hvis du bestemmer deg for å avslutte et betalt abonnement før vi begynner å belaste betalingsmetoden din, må du kansellere abonnementet minst 24 timer før prøveperioden er slutt.\n\nGratis prøveperioder er kun tilgjengelig for nye brukere og utføres etter vårt eget skjønn. Hvis du forsøker å registrere deg med flere gratis prøveperioder, blir du øyeblikkelig belastet standard abonnementsavgift.\n\nVi forbeholder oss retten til å tilbakekalle din gratis prøveperiode når som helst.\n\nEventuell ubrukt del av en gratis prøveperiode går tapt ved kjøpe av et abonnement.\n\nVed å registrere deg samtykker du til disse vilkårene og betingelsene."; +"agreement.message" = "Etter den gratis 7-dagers prøveperioden fornyes abonnementet automatisk for %@, med mindre det kanselleres minst 24 timer før slutten av prøveperioden. Din Apple ID-konto belastes for fornyingen innen 24 timer før slutten av prøveperioden. Du kan administrere og avbryte abonnementene dine ved å gå til App Store-kontoinnstillingene etter kjøp. Det 7-dagers prøvetilbudet er begrenset til én 7-dagers prøveperiode per bruker. Eventuell ubrukt tid av den gratis prøveperioden går tapt hvis brukeren kjøper et abonnement. Alle priser inkluderer gjeldende lokale avgifter.\n\nVed å signere godtar du $1 og $2."; +"agreement.trials.yearly.plan" = "år"; +"agreement.trials.monthly.plan" = "måned"; + +"agreement.message.tos" = "Tjenestevilkår"; +"agreement.message.privacy" = "REntingslinjer om personvern"; + +"getstarted.buttons.buyaccount" = "Kjøpskonto"; + +"gdpr.collect.data.title" = "Personlig informasjon vi tar vare på"; +"gdpr.collect.data.description" = "E-postadresse for kontoadministrasjon og beskyttelse mot misbruk."; +"gdpr.usage.data.title" = "Bruk av personlig informasjon samlet inn av oss"; +"gdpr.usage.data.description" = "E-postadresse blir kun brukt for å sende ut informasjon om abonnementet, betalingsbekreftelser, kundekorrespondanse og tilbud om privat internettilgang."; +"gdpr.accept.button.title" = "Godta og fortsett"; + +"update.account.email.error" = "Kunne ikke endre kontoens e-post"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings new file mode 100644 index 000000000..97c63fd93 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Aanmelding bevestigen"; +"in_progress.message" = "We zijn uw aankoop aan het verifiëren in ons systeem. Dit kan eventjes duren, daarom vragen we u vriendelijk om geduld."; +"in_progress.redeem.message" = "We zijn uw pincode aan het verifiëren in ons systeem. Dit kan eventjes duren, daarom vragen we u vriendelijk om geduld."; + +"success.title" = "Aankoop voltooid"; +"success.message_format" = "Bedankt voor uw aanmelding. We hebben de gebruikersnaam en het wachtwoord voor uw account naar het volgende e-mailadres gestuurd: %@"; +"success.redeem.title" = "Kaart ingewisseld"; +"success.redeem.message" = "U ontvangt zo een e-mail met uw gebruikersnaam en wachtwoord."; +"success.username.caption" = "Gebruikersnaam"; +"success.password.caption" = "Wachtwoord"; +"success.submit" = "Aan de slag"; + +"failure.vc_title" = "Aanmelden mislukt"; +"failure.title" = "Account aanmaken mislukt"; +"failure.message" = "We kunnen op dit moment geen account maken. Probeer het later opnieuw. \n\nAls u de app opnieuw opent, wordt opnieuw geprobeerd een account te maken."; +"failure.purchase.sandbox.message" = "Het geselecteerde sandbox-abonnement is niet beschikbaar in productie."; +"failure.redeem.invalid.title" = "Ongeldige pincode"; +"failure.redeem.invalid.message" = "U heeft een ongeldige pincode ingevoerd. Probeer het opnieuw."; +"failure.redeem.claimed.title" = "Kaart al geclaimd"; +"failure.redeem.claimed.message" = "Deze kaart is door een ander account geclaimd. Probeer een andere pincode."; +"failure.submit" = "GA TERUG"; + +"unreachable.vc_title" = "Fout"; +"unreachable.title" = "Oeps!"; +"unreachable.message" = "Geen internetverbinding gevonden. Controleer uw internetverbinding en probeer het hieronder opnieuw.\n\nU kunt later naar de app terugkeren om het proces te voltooien."; +"unreachable.submit" = "OPNIEUW PROBEREN"; + +"purchase.uncredited.alert.message" = "U heeft niet-gecrediteerde transacties. Wilt u uw accountgegevens herstellen?"; +"purchase.uncredited.alert.button.cancel" = "Annuleren"; +"purchase.uncredited.alert.button.recover" = "Account herstellen"; + +"purchase.trials.intro" = "Start je gratis proefabonnement van 7 dagen"; +"purchase.trials.price.after" = "Daarna %@"; +"purchase.trials.money.back" = "30 dagen lang niet-goed-geld-teruggarantie"; +"purchase.trials.1year.protection" = "1 jaar aan privacy- en identiteitsbescherming"; +"purchase.trials.anonymous" = "Browse anoniem en verberg uw ip."; +"purchase.trials.devices" = "Ondersteun tien apparaten tegelijk"; +"purchase.trials.devices.description" = "Bescherm uzelf op tien apparaten tegelijk."; +"purchase.trials.region" = "Maak eenvoudig verbinding met elke regio"; +"purchase.trials.servers" = "Meer dan 3300 servers in 32 landen"; +"purchase.trials.start" = "Abonnement starten"; +"purchase.trials.all.plans" = "Bekijk de beschikbare abonnementen"; + +"purchase.subscribe.now" = "Nu abonneren"; + +// WALKTHROUGH + +"walkthrough.action.next" = "VOLGENDE"; +"walkthrough.action.done" = "KLAAR"; +"walkthrough.action.skip" = "OVERSLAAN"; + +"walkthrough.page.1.title" = "Ondersteun tien apparaten tegelijk"; +"walkthrough.page.1.description" = "Bescherm uzelf op tien apparaten tegelijk."; +"walkthrough.page.2.title" = "Maak eenvoudig verbinding met elke regio"; +"walkthrough.page.2.description" = "Met servers over de hele wereld wordt u altijd beschermd."; +"walkthrough.page.3.title" = "Bescherm uzelf tegen advertenties"; +"walkthrough.page.3.description" = "Als u onze Content Blocker inschakelt, krijgt u geen advertenties meer te zien in Safari."; + +"share.data.buttons.accept" = "Accepteren"; +"share.data.buttons.noThanks" = "Nee, bedankt"; +"share.data.buttons.readMore" = "Meer informatie"; +"share.data.text.title" = "Help ons onze service te verbeteren"; +"share.data.text.description" = "Om ons te helpen de verbindingsprestaties van onze dienst te verbeteren, kunt u uw verbindingsstatistieken anoniem met ons delen. Deze rapporten bevatten geen persoonsgegevens."; +"share.data.text.footer" = "U kunt dit via de Instellingen beheren"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings new file mode 100644 index 000000000..0131eaac3 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versie %@ (%@)"; +"global.close" = "Sluiten"; +"global.ok" = "OK"; +"global.cancel" = "Annuleren"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings new file mode 100644 index 000000000..3c4007de5 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Aanmelden bij uw account"; +"login.username.placeholder" = "Gebruikersnaam (p1234567)"; +"login.password.placeholder" = "Wachtwoord"; +"login.submit" = "INLOGGEN"; +"login.restore.button" = "Geen accountgegevens ontvangen?"; +"login.error.title" = "Inloggen"; +"login.error.validation" = "U moet een gebruikersnaam en wachtwoord invoeren."; +"login.error.unauthorized" = "Uw gebruikersnaam of wachtwoord is onjuist."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Inloggen met aankoopbewijs"; +"login.magic.link.title" = "Log in met de magische link in uw e-mail"; +"login.magic.link.response" = "Controleer uw e-mail voor een inloglink."; +"login.magic.link.send" = "Link verzenden"; +"login.magic.link.invalid.email" = "Ongeldige e-mail. Probeer het opnieuw."; + +"purchase.title" = "Selecteer een VPN-abonnement"; +"purchase.subtitle" = "30 dagen lang niet-goed-geld-teruggarantie"; +"purchase.email.placeholder" = "E-mailadres"; +"purchase.continue" = "Doorgaan"; +"purchase.login.footer" = "Heeft u al een account?"; +"purchase.login.button" = "Aanmelden"; +"purchase.error.title" = "Kopen"; +"purchase.error.validation" = "U moet een e-mailadres invoeren"; +"purchase.error.connectivity.title" = "Verbindingsfout"; +"purchase.error.connectivity.description" = "We kunnen Private Internet Access niet bereiken. Dit kan komen door een slechte internetverbinding of omdat onze dienst in uw land is geblokkeerd."; +"purchase.confirm.form.email" = "Voer uw e-mailadres in"; +"purchase.confirm.plan" = "U koop het %@-abonnement"; +"purchase.email.why" = "We hebben uw e-mailadres nodig om uw gebruikersnaam en wachtwoord te versturen."; +"purchase.submit" = "Versturen"; +"purchase.or" = "of"; + +"upgrade.header" = "Welkom terug!"; +"upgrade.title" = "U moet uw abonnement vernieuwen om Private Internet Access te kunnen gebruiken."; +"upgrade.renew.now" = "Nu vernieuwen"; + + + +"redeem.title" = "Cadeaubon inwisselen"; +"redeem.subtitle" = "Voer uw e-mailadres en de %lu-cijferige pincode van uw cadeaubon of proefperiodekaart hieronder in."; +"redeem.email.placeholder" = "E-mailadres"; +"redeem.submit" = "VERSTUREN"; +"redeem.error.title" = "Inwisselen"; +"redeem.error.code" = "Code moet uit %lu getallen bestaan."; +"redeem.error.allfields" = "Voer uw e-mailadres en pincode in."; +"redeem.accessibility.back" = "Terug"; +"redeem.giftcard.placeholder" = "Pincode cadeaubon"; + +"plan.monthly.title" = "Maandelijks"; +"plan.yearly.title" = "Jaarlijks"; +"plan.yearly.detail_format" = "%@%@ per jaar"; +"plan.price_format" = "%@/ma"; +"plan.best_value" = "Beste waarde"; +"plan.accessibility.per_month" = "per maand"; + +"restore.title" = "Aankoop herstellen"; +"restore.subtitle" = "Als u een abonnement via deze app heeft aangeschaft en u heeft uw gegevens niet ontvangen, dan kunt u ze hier opnieuw verzenden. Er worden geen kosten in rekening gebracht tijdens dit proces."; +"restore.email.placeholder" = "E-mailadres"; +"restore.submit" = "BEVESTIGEN"; + +"iap.error.message.unavailable" = "De Apple-servers zijn momenteel niet beschikbaar. Probeer het later opnieuw."; +"iap.error.title" = "Fout"; + +"agreement.trials.title" = "Algemene voorwaarden gratis proefabonnementen"; +"agreement.trials.message" = "De betaling wordt bij de bevestiging van uw aankoop via uw Apple ID-account in rekening gebracht. Het abonnement wordt automatisch verlengd, tenzij het ten minste 24 uur voor het einde van de huidige periode wordt geannuleerd. De verlenging van uw account wordt binnen 24 uur voor het einde van de huidige periode in rekening gebracht. U kunt uw abonnementen beheren en annuleren door na de aankoop naar uw accountinstellingen in de App Store te gaan.\n\nBepaalde betaalde abonnementen kunnen een gratis proefabonnement aanbieden voordat er kosten in rekening worden gebracht. Als u zich wilt afmelden voor een betaald abonnement voordat we kosten in rekening brengen, moet u het abonnement ten minste 24 uur voor het einde van de gratis proefperiode annuleren.\n\nGratis proefabonnementen zijn alleen beschikbaar voor nieuwe gebruikers. Als u zich aanmeldt voor een aanvullend gratis proefabonnement worden onmiddellijk de standaard abonnementskosten in rekening gebracht.\n\nWij behouden ons het recht voor om uw gratis proefabonnement te allen tijde in te trekken.\n\nEen eventueel ongebruikt deel van uw gratis proefperiode vervalt bij aankoop van een abonnement.\n\nAls u zich aanmeldt, gaat u akkoord met deze algemene voorwaarden."; +"agreement.message" = "Na de gratis proefperiode van 7 dagen wordt het abonnement automatisch verlengd voor %@, tenzij u het ten minste 24 uur voor het einde van de proefperiode annuleert. De kosten voor de verlenging worden binnen 24 uur voor het einde van de proefperiode via uw Apple ID-account in rekening gebracht. U kunt uw abonnementen beheren en annuleren door na de aankoop naar uw accountinstellingen in de App Store te gaan. De proefperiode van 7 dagen is beperkt tot één proefperiode van 7 dagen per gebruiker. Een eventueel ongebruikt deel van uw gratis proefperiode vervalt bij aankoop van een abonnement. Alle prijzen zijn inclusief lokale omzetbelasting, indien van toepassing.\n\nAls u zich aanmeldt, gaat u akkoord met de $1 en het $2."; +"agreement.trials.yearly.plan" = "jaar"; +"agreement.trials.monthly.plan" = "maand"; + +"agreement.message.tos" = "Servicevoorwaarden"; +"agreement.message.privacy" = "Privacybeleid"; + +"getstarted.buttons.buyaccount" = "Account kopen"; + +"gdpr.collect.data.title" = "Persoonlijke informatie die we verzamelen"; +"gdpr.collect.data.description" = "E-mailadres voor accountbeheer en bescherming tegen misbruik."; +"gdpr.usage.data.title" = "Gebruik van de persoonlijke informatie die we verzamelen"; +"gdpr.usage.data.description" = "E-mailadres wordt alleen gebruikt voor het verzenden van abonnementsinformatie, betalingsbevestigingen, correspondentie met klanten en promotionele aanbiedingen van Private Internet Access."; +"gdpr.accept.button.title" = "Akkoord en doorgaan"; + +"update.account.email.error" = "Kan accountmail niet aanpassen"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings new file mode 100644 index 000000000..9922f65c3 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Potwierdź rejestrację"; +"in_progress.message" = "Potwierdzamy zakup w naszym systemie. Poczekaj spokojnie, bo to może trochę potrwać."; +"in_progress.redeem.message" = "Potwierdzamy Twój PIN karty w naszym systemie, TO może chwilę potrwać, więc prosimy o cierpliwość."; + +"success.title" = "Zakup zakończony"; +"success.message_format" = "Dziękujemy za rejestrację. Przesłaliśmy Twoją nazwę użytkownika i hasło na Twój adres e-mail: %@"; +"success.redeem.title" = "Karta została wymieniona"; +"success.redeem.message" = "Wkrótce otrzymasz e-mail z nazwą użytkownika i hasłem.\n\nTwoje dane do logowania"; +"success.username.caption" = "Nazwa użytkownika"; +"success.password.caption" = "Hasło"; +"success.submit" = "Rozpocznij"; + +"failure.vc_title" = "Rejestracja nie powiodła się"; +"failure.title" = "Błąd tworzenia konta"; +"failure.message" = "Obecnie nie możemy utworzyć konta. Spróbuj ponownie później."; +"failure.purchase.sandbox.message" = "Wybrana subskrypcja na piaskownicę (środowisko testowe) nie jest dostępna w produkcji."; +"failure.redeem.invalid.title" = "Nieprawidłowy PIN karty"; +"failure.redeem.invalid.message" = "Wygląda na to, ze wpisałeś nieprawidłowy PIN karty. Spróbuj ponownie."; +"failure.redeem.claimed.title" = "Karta już użyta"; +"failure.redeem.claimed.message" = "Wygląda na to, że ta karta została użyta na innym koncie. Możesz spróbować wpisać inny PIN."; +"failure.submit" = "WSTECZ"; + +"unreachable.vc_title" = "Błąd"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Nie znaleziono połączenia z internetem. Potwierdź, że masz połączenie z internetem i naciśnij „Spróbuj ponownie” poniżej..\n\nMożesz wrócić do aplikacji później, aby dokończyć proces."; +"unreachable.submit" = "SPRÓBUJ PONOWNIE"; + +"purchase.uncredited.alert.message" = "Masz nieuznane transakcje. Chcesz odzyskać dane swojego konta?"; +"purchase.uncredited.alert.button.cancel" = "Anuluj"; +"purchase.uncredited.alert.button.recover" = "Odzyskaj konto"; + +"purchase.trials.intro" = "Zacznij 7-dniowy bezpłatny okres próbny"; +"purchase.trials.price.after" = "Potem %@"; +"purchase.trials.money.back" = "30-dniowa gwarancja zwrotu pieniędzy"; +"purchase.trials.1year.protection" = "1 rok ochrony prywatności i tożsamości"; +"purchase.trials.anonymous" = "Przeglądaj sieć anonimowa i ukryj swoje IP"; +"purchase.trials.devices" = "Obsługa 10 urządzeń jednocześnie"; +"purchase.trials.devices.description" = "Ochrona na maksymalnie 10 urządzeniach jednocześnie."; +"purchase.trials.region" = "Łatwo połączysz się z dowolnym regionem"; +"purchase.trials.servers" = "Ponad 3300 serwerów w 32 krajach"; +"purchase.trials.start" = "Rozpocznij subskrypcję"; +"purchase.trials.all.plans" = "Sprawdź wszystkie dostępne plany"; + +"purchase.subscribe.now" = "Subskrybuj teraz"; + +// WALKTHROUGH + +"walkthrough.action.next" = "DALEJ"; +"walkthrough.action.done" = "GOTOWE"; +"walkthrough.action.skip" = "POMIŃ"; + +"walkthrough.page.1.title" = "Obsługa 10 urządzeń jednocześnie"; +"walkthrough.page.1.description" = "Ochrona na maksymalnie 10 urządzeniach jednocześnie."; +"walkthrough.page.2.title" = "Łatwo połączysz się z dowolnym regionem"; +"walkthrough.page.2.description" = "Dzięki serwerom na całym świecie zawsze jesteś pod ochroną."; +"walkthrough.page.3.title" = "Unikaj reklam"; +"walkthrough.page.3.description" = "Włączenie naszej Blokady zawartości chroni Cię przed wyświetlaniem reklam w Safari."; + +"share.data.buttons.accept" = "Akceptuj"; +"share.data.buttons.noThanks" = "Nie, dziękuję"; +"share.data.buttons.readMore" = "Dowiedz się więcej"; +"share.data.text.title" = "Prosimy o pomoc w ulepszeniu naszych usług"; +"share.data.text.description" = "Aby pomóc nam zapewnić najlepszą wydajność naszych usług, możesz anonimowo udostępniać nam swoje statystyki połączeń. Raporty te nie zawierają żadnych informacji umożliwiających identyfikację osób."; +"share.data.text.footer" = "Zawsze możesz to kontrolować w swoich ustawieniach"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings new file mode 100644 index 000000000..fccbc42bf --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Wersja %@ (%@)"; +"global.close" = "Zamknij"; +"global.ok" = "OK"; +"global.cancel" = "Anuluj"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings new file mode 100644 index 000000000..1af0054e2 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Zaloguj się na konto"; +"login.username.placeholder" = "Nazwa użytkownika (p1234567)"; +"login.password.placeholder" = "Hasło"; +"login.submit" = "ZALOGUJ"; +"login.restore.button" = "Nie dostałeś(-aś) Danych swojego konta?"; +"login.error.title" = "Zaloguj"; +"login.error.validation" = "Musisz podać nazwę użytkownika i hasło."; +"login.error.unauthorized" = "Twoja nazwa użytkownika i hasło są nieprawidłowe."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Zaloguj się, używając pokwitowania zakupu"; +"login.magic.link.title" = "Zaloguj się, używając sekretnego linku z e-maila"; +"login.magic.link.response" = "Link do logowania wysłaliśmy e-mailem,"; +"login.magic.link.send" = "Wyślij link"; +"login.magic.link.invalid.email" = "Nieprawidłowy e-mail. Spróbuj ponownie"; + +"purchase.title" = "Wybierz plan VPN"; +"purchase.subtitle" = "30-dniowej gwarancji zwrotu pieniędzy"; +"purchase.email.placeholder" = "Adres e-mail"; +"purchase.continue" = "Kontynuuj"; +"purchase.login.footer" = "Masz już konto?"; +"purchase.login.button" = "Zaloguj"; +"purchase.error.title" = "Zakup"; +"purchase.error.validation" = "Musisz podać adres e-mail."; +"purchase.error.connectivity.title" = "Błąd połączenia"; +"purchase.error.connectivity.description" = "Nie można połączyć z Private Internet Access. Może to być spowodowane słabym połączeniem z internetem lub nasza usługa może być zablokowana w Twoim kraju."; +"purchase.confirm.form.email" = "Podaj swój adres e-mail"; +"purchase.confirm.plan" = "Kupujesz abonament %@"; +"purchase.email.why" = "Twój e-mail jest nam potrzebny do przesłania Ci nazwy użytkownika i hasła,"; +"purchase.submit" = "Wyślij"; +"purchase.or" = "lub"; + +"upgrade.header" = "Witaj ponownie!"; +"upgrade.title" = "Aby korzystać z Private Internet Access, musisz odnowić swoją subskrypcję."; +"upgrade.renew.now" = "Odnów teraz"; + + + +"redeem.title" = "Wykorzystaj kartę podarunkową"; +"redeem.subtitle" = "Wpisz swój adres e-mail oraz %lu-cyfrowy PIN z karty podarunkowej lub karty próbnej poniżej."; +"redeem.email.placeholder" = "Adres e-mail"; +"redeem.submit" = "PRZEŚLIJ"; +"redeem.error.title" = "Wykorzystaj"; +"redeem.error.code" = "Kod musi składać się z %lu znaków numerycznych."; +"redeem.error.allfields" = "Podaj swój adres r-mail i PIN karty"; +"redeem.accessibility.back" = "Wstecz"; +"redeem.giftcard.placeholder" = "PIN karty upominkowej"; + +"plan.monthly.title" = "Miesięcznie"; +"plan.yearly.title" = "Rocznie"; +"plan.yearly.detail_format" = "%@%@ rocznie"; +"plan.price_format" = "%@/msc."; +"plan.best_value" = "Najlepsza wartość"; +"plan.accessibility.per_month" = "miesięcznie"; + +"restore.title" = "Przywróć pominięty zakup"; +"restore.subtitle" = "Jeśli kupił(a)ś abonament, korzystając z tej aplikacji, ale nie dostałe(a)ś danych logowania, możesz wysłać je ponownie stąd.\nOpłata nie zostanie za to pobrana za tę czynność"; +"restore.email.placeholder" = "Adres e-mail"; +"restore.submit" = "POTWIERDŹ"; + +"iap.error.message.unavailable" = "Serwery Apple'a są w tej chwili niedostępne. Spróbuj ponownie później."; +"iap.error.title" = "Błąd"; + +"agreement.trials.title" = "Regulamin korzystania z bezpłatnej wersji próbnej"; +"agreement.trials.message" = "Płatność zostanie pobrana z Twojego konta Apple ID z chwilą potwierdzenia zakupu. Subskrypcja odnawia się automatycznie, chyba że zostanie anulowana co najmniej 24 godziny przed końcem bieżącego okresu rozliczeniowego. Opłata za odnowienie subskrypcji zostanie pobrana w ciągu 24 godzin przed końcem bieżącego okresu. Możesz zarządzać subskrypcjami i je anulować, przechodząc do ustawień konta w App Store po dokonaniu zakupu.\n\nCzęść płatnych Subskrypcji może obejmować bezpłatną wersję próbną, z której możesz skorzystać przed naliczeniem opłaty. Jeśli postanowisz zrezygnować z płatnej subskrypcji przed rozpoczęciem naliczania opłat zgodnie z wybraną metodą płatności, anuluj subskrypcję co najmniej 24 godziny przed zakończeniem bezpłatnej wersji próbnej.\n\nBezpłatne wersje próbne są dostępne tylko dla nowych użytkowników i są przyznawane wyłącznie według naszego uznania, a w przypadku próby zarejestrowania w celu uzyskania dodatkowej bezpłatnej wersji próbnej, zostaniesz natychmiast obciążony standardową opłatą subskrypcyjną.\n\nRejestracja oznacza akceptację niniejszego regulaminu."; +"agreement.message" = "Po 7 dniach bezpłatnego okresu próbnego ta subskrypcja odnowi się automatycznie na %@, jeżeli nie zostanie anulowana co najmniej 24 godziny przed końcem okresu próbnego. Twoje konto Apple ID zostanie obciążone opłatą za odnowienie w ciągu 24 godzin przed końcem okresu próbnego. Możesz zarządzać swoimi subskrypcjami i je anulować, wchodząc po zakupie w ustawienia swojego konta w App Store Oferta 7-dniowego okresu próbnego jest ograniczona – każdemu użytkownikowi przysługuje jeden 7-dniowy okres próbny. Każda niewykorzystana część bezpłatnego okresu próbnego, jeśli zostanie zaoferowany, przepada wraz zakupem subskrypcji przez użytkownika. Wszystkie ceny zawierają obowiązujące lokalne podatki obrotowe.\n\nRejestracja oznacza akceptację artykułów. $1 i $2."; +"agreement.trials.yearly.plan" = "rok"; +"agreement.trials.monthly.plan" = "miesiąc"; + +"agreement.message.tos" = "Warunki użytkowania"; +"agreement.message.privacy" = "Zasady ochrony prywatności"; + +"getstarted.buttons.buyaccount" = "Zakup konto"; + +"gdpr.collect.data.title" = "Zbierane dane osobowe"; +"gdpr.collect.data.description" = "Adres e-mail do zarządzania kontem i ochrony przed nadużyciami."; +"gdpr.usage.data.title" = "Sposoby wykorzystania zbieranych przez nas danych osobowych"; +"gdpr.usage.data.description" = "Adres e-mail; używany go do wysyłania informacji o subskrypcji, potwierdzeń płatności, korespondencji z klientami i wysyłania ofert promocyjnych wyłącznie Private Internet Access"; +"gdpr.accept.button.title" = "Zaakceptuj i kontynuuj"; + +"update.account.email.error" = "Nie udało się zmienić adresu e-mail konta"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings new file mode 100644 index 000000000..5bcf7cb9a --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirme o registro"; +"in_progress.message" = "Confirmamos sua compra com o nosso sistema. Isso pode demorar um pouco. Por favor, aguarde."; +"in_progress.redeem.message" = "Estamos confirmando o PIN do seu cartão com o nosso sistema. Isso pode demorar um pouco. Por favor, aguarde."; + +"success.title" = "Compra Concluída"; +"success.message_format" = "Obrigado por se registrar conosco. Nós enviamos o nome de usuário e a senha da sua conta para o seu endereço de e-mail em %@"; +"success.redeem.title" = "Cartão resgatado com sucesso"; +"success.redeem.message" = "Você receberá um e-mail com seu nome de usuário e senha em breve.\n\nSeus dados de login"; +"success.username.caption" = "Nome de usuário"; +"success.password.caption" = "Senha"; +"success.submit" = "Comece Agora"; + +"failure.vc_title" = "Falha ao registrar"; +"failure.title" = "Falha ao Criar Conta"; +"failure.message" = "Não podemos criar uma conta neste momento. Tente novamente mais tarde.\n\nApós a reabertua do aplicativo, uma nova tentativa de criação de conta será realizada."; +"failure.purchase.sandbox.message" = "A assinatura da área restrita selecionada não está disponível em produção."; +"failure.redeem.invalid.title" = "PIN de cartão inválido"; +"failure.redeem.invalid.message" = "Parece que você inseriu um PIN de cartão inválido. Por favor, tente novamente."; +"failure.redeem.claimed.title" = "O cartão já foi resgatado"; +"failure.redeem.claimed.message" = "Parece que este cartão já foi resgatado por outra conta. Você pode tentar usar um PIN diferente."; +"failure.submit" = "VOLTAR"; + +"unreachable.vc_title" = "Erro"; +"unreachable.title" = "Ops!"; +"unreachable.message" = "Nenhuma conexão com a Internet encontrada. Confirme que você possui uma conexão com a Internet e pressione Tentar Novamente abaixo.\n\nVocê pode retornar ao aplicativo mais tarde para finalizar o processo."; +"unreachable.submit" = "TENTAR NOVAMENTE"; + +"purchase.uncredited.alert.message" = "Você tem transações não creditadas. Deseja recuperar os detalhes da sua conta?"; +"purchase.uncredited.alert.button.cancel" = "Cancelar"; +"purchase.uncredited.alert.button.recover" = "Recuperar conta"; + +"purchase.trials.intro" = "Comece sua avaliação gratuita de 7 dias"; +"purchase.trials.price.after" = "Em seguida, %@"; +"purchase.trials.money.back" = "Garantia do dinheiro de volta em até 30 dias"; +"purchase.trials.1year.protection" = "1 ano de proteção de privacidade e identidade"; +"purchase.trials.anonymous" = "Navegue anonimamente e oculte seu IP."; +"purchase.trials.devices" = "Suporte para 10 dispositivos ao mesmo tempo"; +"purchase.trials.devices.description" = "Proteja-se em até 10 dispositivos ao mesmo tempo."; +"purchase.trials.region" = "Conecte-se a qualquer região facilmente"; +"purchase.trials.servers" = "Mais de 3.300 servidores em 32 países"; +"purchase.trials.start" = "Iniciar assinatura"; +"purchase.trials.all.plans" = "Veja todos os planos disponíveis"; + +"purchase.subscribe.now" = "Assine agora"; + +// WALKTHROUGH + +"walkthrough.action.next" = "AVANÇAR"; +"walkthrough.action.done" = "CONCLUÍDO"; +"walkthrough.action.skip" = "PULAR"; + +"walkthrough.page.1.title" = "Suporte para 10 dispositivos ao mesmo tempo"; +"walkthrough.page.1.description" = "Proteja-se em até 10 dispositivos ao mesmo tempo."; +"walkthrough.page.2.title" = "Conecte-se a qualquer região facilmente"; +"walkthrough.page.2.description" = "Com servidores ao redor do mundo, você está sempre protegido."; +"walkthrough.page.3.title" = "Proteja-se contra propagandas"; +"walkthrough.page.3.description" = "A ativação do nosso Bloqueador de Conteúdo impede que anúncios sejam exibidos no Safari."; + +"share.data.buttons.accept" = "Aceitar"; +"share.data.buttons.noThanks" = "Não, obrigado"; +"share.data.buttons.readMore" = "Leia mais"; +"share.data.text.title" = "Ajude-nos a melhorar nosso serviço"; +"share.data.text.description" = "Para nos ajudar a garantir o desempenho da conexão de nosso serviço, você pode compartilhar anonimamente as estatísticas da sua conexão conosco. Esses relatórios não incluem nenhuma informação de identificação pessoal."; +"share.data.text.footer" = "Você sempre poderá controlar isso em suas configurações"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings new file mode 100644 index 000000000..32e6d7e28 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versão %@ (%@)"; +"global.close" = "Fechar"; +"global.ok" = "OK"; +"global.cancel" = "Cancelar"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings new file mode 100644 index 000000000..7ed6d1e85 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Entre na sua conta"; +"login.username.placeholder" = "Nome de usuário (p1234567)"; +"login.password.placeholder" = "Senha"; +"login.submit" = "ENTRAR"; +"login.restore.button" = "Não recebeu detalhes da conta?"; +"login.error.title" = "Entrar"; +"login.error.validation" = "Você deve inserir um nome de usuário e senha."; +"login.error.unauthorized" = "Seu nome de usuário ou senha está incorreto."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Faça login usando o recibo de compra"; +"login.magic.link.title" = "Faça login usando o link mágico enviado por e-mail"; +"login.magic.link.response" = "Veja se você recebeu por e-mail um link para fazer login."; +"login.magic.link.send" = "Enviar link"; +"login.magic.link.invalid.email" = "E-mail inválido. Tente novamente."; + +"purchase.title" = "Selecione um plano de VPN"; +"purchase.subtitle" = "Garantia do dinheiro de volta em até 30 dias"; +"purchase.email.placeholder" = "Endereço de e-mail"; +"purchase.continue" = "Continuar"; +"purchase.login.footer" = "Já tem uma conta?"; +"purchase.login.button" = "Faça login"; +"purchase.error.title" = "Comprar"; +"purchase.error.validation" = "Você precisa inserir um endereço de e-mail."; +"purchase.error.connectivity.title" = "Falha na conexão"; +"purchase.error.connectivity.description" = "Não conseguimos acessar o Private Internet Access. Isso pode ser devido a uma conexão de internet fraca ou o nosso serviço está bloqueado em seu país."; +"purchase.confirm.form.email" = "Insira seu endereço de e-mail"; +"purchase.confirm.plan" = "Você está adquirindo o plano %@"; +"purchase.email.why" = "Precisamos do seu e-mail para enviarmos seu nome de usuário e senha."; +"purchase.submit" = "Enviar"; +"purchase.or" = "ou"; + +"upgrade.header" = "Seja bem-vindo(a)!"; +"upgrade.title" = "Para usar a Private Internet Access, você precisará renovar sua assinatura."; +"upgrade.renew.now" = "Renovar agora"; + + + +"redeem.title" = "Resgatar cartão-presente"; +"redeem.subtitle" = "Digite o seu endereço de e-mail e o PIN de %lu dígitos do seu cartão-presente ou cartão de teste abaixo."; +"redeem.email.placeholder" = "Endereço de e-mail"; +"redeem.submit" = "ENVIAR"; +"redeem.error.title" = "Resgatar"; +"redeem.error.code" = "O código precisa ter %lu dígitos numéricos."; +"redeem.error.allfields" = "Digite o seu e-mail e PIN do cartão."; +"redeem.accessibility.back" = "Voltar"; +"redeem.giftcard.placeholder" = "PIN do cartão-presente"; + +"plan.monthly.title" = "Mensal"; +"plan.yearly.title" = "Anual"; +"plan.yearly.detail_format" = "%@%@ por ano"; +"plan.price_format" = "%@/mês"; +"plan.best_value" = "Melhor valor"; +"plan.accessibility.per_month" = "por mês"; + +"restore.title" = "Restaurar compra não creditada"; +"restore.subtitle" = "Se você adquiriu um plano por este aplicativo e não recebeu as suas credenciais, você pode enviá-las novamente por aqui. Você não será cobrado durante esse processo."; +"restore.email.placeholder" = "Endereço de e-mail"; +"restore.submit" = "CONFIRMAR"; + +"iap.error.message.unavailable" = "Servidores da Apple indisponíveis no momento. Tente novamente mais tarde."; +"iap.error.title" = "Erro"; + +"agreement.trials.title" = "Termos e condições das avaliações gratuitas"; +"agreement.trials.message" = "O pagamento será cobrado na sua conta do ID Apple no ato da confirmação da compra. A assinatura será renovada automaticamente, a não ser que ela seja cancelada, pelo menos, 24 horas antes do fim do período atual. O valor da renovação será debitado na sua conta em até 24 horas antes do término do período da atual. Você pode gerenciar e cancelar suas assinaturas nos ajustes da conta na App Store após a compra.\n\nCertas assinaturas pagas podem oferecer uma avaliação gratuita antes da cobrança do pagamento. Se você decidir cancelar uma Assinatura Paga antes de começarmos a cobrar por ela, cancele-a, pelo menos, 24 horas antes do término da avaliação gratuita.\n\nAs avaliações gratuitas estão disponíveis apenas para novos usuários, e são a nosso critério. Se tentar se registrar para uma avaliação gratuita adicional, você será cobrado imediatamente com a Taxa de Assinatura padrão.\n\nReservamo-nos o direito de revogar sua avaliação gratuita a qualquer momento.\n\nQualquer parte não utilizada do período da sua avaliação gratuita será perdida após a compra de uma assinatura.\n\nO registro constitui da aceitação dos termos e condições."; +"agreement.message" = "Após os 7 dias da avaliação gratuita, a assinatura será renovada automaticamente por %@, a não ser que ela seja cancelada, pelo menos, 24 horas antes do término do período de avaliação. O valor da renovação será debitado da conta do seu ID Apple em até 24 horas antes do término do período de avaliação. Você pode gerenciar e cancelar suas assinaturas nos ajustes da conta da App Store após a compra. A oferta de avaliação de 7 dias é limitada a uma oferta de avaliação de 7 dias por usuário. Qualquer parte não utilizada do período de avaliação gratuita, se oferecida, será perdida após a aquisição de uma assinatura. Todos os preços incluem impostos de vendas locais aplicáveis.\n\nO registro constitui da aceitação dos $1 e da $2."; +"agreement.trials.yearly.plan" = "ano"; +"agreement.trials.monthly.plan" = "mês"; + +"agreement.message.tos" = "Termos de Serviço"; +"agreement.message.privacy" = "Política de Privacidade"; + +"getstarted.buttons.buyaccount" = "Comprar conta"; + +"gdpr.collect.data.title" = "Informações pessoais que coletamos"; +"gdpr.collect.data.description" = "Endereço de e-mail para gerenciamento de conta e proteção contra abuso."; +"gdpr.usage.data.title" = "Uso de informações pessoais coletadas por nós"; +"gdpr.usage.data.description" = "O endereço de e-mail é utilizado apenas para enviar informação de assinatura, confirmações de pagamento, correspondência com clientes e ofertas promocionais do Private Internet Access."; +"gdpr.accept.button.title" = "Concordar e continuar"; + +"update.account.email.error" = "Falha ao modificar o e-mail da conta"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings new file mode 100644 index 000000000..9f032f794 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Подтверждение регистрации"; +"in_progress.message" = "Мы проверяем вашу покупку в системе. На это может понадобиться время, так что оставайтесь с нами."; +"in_progress.redeem.message" = "Мы подтверждаем ваш PIN-код в системе. Это займет какое-то время, подождите немного."; + +"success.title" = "Покупка завершена"; +"success.message_format" = "Спасибо за регистрацию. Мы отправили имя пользователя и пароль на адрес электронной почты %@"; +"success.redeem.title" = "Карта успешно использована"; +"success.redeem.message" = "Также вы получите эл. письмо с именем пользователя и паролем.\n\nВаши учетные данные"; +"success.username.caption" = "Имя пользователя"; +"success.password.caption" = "Пароль"; +"success.submit" = "Начать"; + +"failure.vc_title" = "Ошибка регистрации"; +"failure.title" = "Сбой создания учетной записи"; +"failure.message" = "Нам не удалось создать учетную запись. Повторите попытку позже.\nПри повторном открытии приложения создание учетной записи будет возобновлено."; +"failure.purchase.sandbox.message" = "Выбранная подписка на «песочницу» недоступна в производственной среде."; +"failure.redeem.invalid.title" = "Неверный PIN-код карты"; +"failure.redeem.invalid.message" = "Похоже, вы ввели неверный PIN-код карты. Попробуйте еще раз."; +"failure.redeem.claimed.title" = "Карта уже использована"; +"failure.redeem.claimed.message" = "Похоже, эту карту уже использовали с другой учетной записи. Попробуйте ввести другой PIN."; +"failure.submit" = "ВОЗВРАТ"; + +"unreachable.vc_title" = "Ошибка"; +"unreachable.title" = "Ой!"; +"unreachable.message" = "Интернет-соединение не найдено. Пожалуйста, убедитесь, что у вас есть подключение к Интернету, и повторите попытку позже.\n\nМожно вернуться в приложение позже и завершить процесс."; +"unreachable.submit" = "ПОВТОРИТЬ"; + +"purchase.uncredited.alert.message" = "У вас есть непроведенные транзакции. Хотите восстановить данные своей учетной записи?"; +"purchase.uncredited.alert.button.cancel" = "Отмена"; +"purchase.uncredited.alert.button.recover" = "Восстановить учетную запись"; + +"purchase.trials.intro" = "Начните 7-дневную бесплатную пробу"; +"purchase.trials.price.after" = "После этого %@"; +"purchase.trials.money.back" = "30-дневная гарантия возврата денег"; +"purchase.trials.1year.protection" = "1 год защиты конфиденциальности и личных данных"; +"purchase.trials.anonymous" = "Пользуйтесь Интернетом анонимно и скрывайте свой IP-адрес."; +"purchase.trials.devices" = "Поддержка сразу 10 устройств"; +"purchase.trials.devices.description" = "Защищайте себя на нескольких устройствах одновременно (до 10)."; +"purchase.trials.region" = "Простое подключение к любому региону"; +"purchase.trials.servers" = "Более 3300 серверов в 32 странах"; +"purchase.trials.start" = "Запустить подписку."; +"purchase.trials.all.plans" = "Смотреть все доступные планы"; + +"purchase.subscribe.now" = "Подписаться"; + +// WALKTHROUGH + +"walkthrough.action.next" = "ДАЛЕЕ"; +"walkthrough.action.done" = "ГОТОВО"; +"walkthrough.action.skip" = "ПРОПУСК"; + +"walkthrough.page.1.title" = "Поддержка 10 устройств одновременно"; +"walkthrough.page.1.description" = "Защищайте себя на нескольких устройствах одновременно (до 10)."; +"walkthrough.page.2.title" = "Простое подключение к любому региону"; +"walkthrough.page.2.description" = "У нас есть серверы по всему миру, так что вы всегда будете под защитой."; +"walkthrough.page.3.title" = "Защита от рекламы"; +"walkthrough.page.3.description" = "Активация нашего правила блокирования контента препятствует отображению рекламы в Safari."; + +"share.data.buttons.accept" = "Принять"; +"share.data.buttons.noThanks" = "Спасибо, не надо"; +"share.data.buttons.readMore" = "Подробнее"; +"share.data.text.title" = "Помогите нам сделать нашу службу еще лучше"; +"share.data.text.description" = "Вы можете анонимно делиться с нами своей статистикой соединения, чтобы помочь нам обеспечить производительность подключения нашей службы. Эти отчеты не включают какую-либо личную информацию."; +"share.data.text.footer" = "Вы всегда можете управлять этим параметром через настройки"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings new file mode 100644 index 000000000..2d1416365 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Версия %@ (%@)"; +"global.close" = "Закрыть"; +"global.ok" = "ОК"; +"global.cancel" = "Отмена"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings new file mode 100644 index 000000000..cd0684978 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Войдите в свою учетную запсь"; +"login.username.placeholder" = "Имя пользователя (p1234567)"; +"login.password.placeholder" = "Пароль"; +"login.submit" = "ВХОД"; +"login.restore.button" = "Не получили данные учетной записи?"; +"login.error.title" = "Войти"; +"login.error.validation" = "Нужно ввести имя пользователя и пароль."; +"login.error.unauthorized" = "Неправильное имя пользователя или пароль."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Выполните вход по квитанции о покупке"; +"login.magic.link.title" = "Войти через волшебную ссылку из письма"; +"login.magic.link.response" = "Поищите ссылку для входа в письме."; +"login.magic.link.send" = "Отправить ссылку"; +"login.magic.link.invalid.email" = "Недействительный эл. адрес. Повторите попытку."; + +"purchase.title" = "Выберите план VPN"; +"purchase.subtitle" = "30-дневная гарантия возврата денег"; +"purchase.email.placeholder" = "Адрес эл. почты"; +"purchase.continue" = "Продолжить"; +"purchase.login.footer" = "Уже есть учетная запись?"; +"purchase.login.button" = "Вход"; +"purchase.error.title" = "Купить"; +"purchase.error.validation" = "Укажите адрес эл. почты."; +"purchase.error.connectivity.title" = "Ошибка подключения"; +"purchase.error.connectivity.description" = "Не удалось подключиться к Private Internet Access. Это может быть из-за плохого качества соединения с Интернетом, или наша служба заблокирована в вашей стране."; +"purchase.confirm.form.email" = "Введите свой адрес эл. почты"; +"purchase.confirm.plan" = "Вы приобретаете план «%@»"; +"purchase.email.why" = "Нам нужен ваш электронный адрес, чтобы мы могли прислать вам имя пользователя и пароль."; +"purchase.submit" = "Отправить"; +"purchase.or" = "или"; + +"upgrade.header" = "С возвращением!"; +"upgrade.title" = "Чтобы пользоваться Private Internet Access, вам необходимо продлить подписку."; +"upgrade.renew.now" = "Продлить"; + + + +"redeem.title" = "Исп-ть подарочную карту"; +"redeem.subtitle" = "Введите свой адрес эл. почты и %lu-зн. PIN-код с подарочной или триальной карты."; +"redeem.email.placeholder" = "Адрес эл. почты"; +"redeem.submit" = "ОТПРАВИТЬ"; +"redeem.error.title" = "Использовать"; +"redeem.error.code" = "В коде должно быть %lu цифр(ы)."; +"redeem.error.allfields" = "Введите свой эл. адрес и PIN-код карты"; +"redeem.accessibility.back" = "Назад"; +"redeem.giftcard.placeholder" = "PIN-код подарочной карты"; + +"plan.monthly.title" = "Ежемесячно"; +"plan.yearly.title" = "Ежегодно"; +"plan.yearly.detail_format" = "%@%@ в год"; +"plan.price_format" = "%@/мес."; +"plan.best_value" = "Максимальная выгода"; +"plan.accessibility.per_month" = "в месяц"; + +"restore.title" = "Восстановить непроведенную покупку"; +"restore.subtitle" = "Если вы купили план через это приложение и не получили учетных данных, вы можете повторно отправить их отсюда. За эту процедуру не взимается плата."; +"restore.email.placeholder" = "Адрес электронной почты"; +"restore.submit" = "ПОДТВЕРДИТЬ"; + +"iap.error.message.unavailable" = "Серверы Apple временно недоступны. Повторите попытку позже."; +"iap.error.title" = "Ошибка"; + +"agreement.trials.title" = "Положения и условия бесплатного пробного пользования"; +"agreement.trials.message" = "Платеж списывается со счета вашего Apple ID при подтверждении покупки. Подписка продлевается автоматически, если не отменить ее по меньшей мере за 24 часа до окончания текущего периода. Плата за продление подписки будет списана со счета вашей учетной записи в течение 24 часов до окончания текущего периода. Для управления подписками, в том числе их отмены, после покупки перейдите в настройки учетной записи в App Store.\n\nНекоторые платные подписки могут предлагать бесплатное пробное пользование перед тем, как списывать средства с использованием указанного вами способа оплаты. Если вы решите отменить платную подписку до того, как мы начнем списывать средства с использованием указанного вами способа оплаты, сделайте это по меньшей мере за 24 часа до окончания бесплатного пробного периода.\n\nБесплатное пробное пользование доступно только для новых пользователей и предлагается по нашему единоличному усмотрению, и если вы попытаетесь зарегистрироваться для участия в дополнительном бесплатном пробном пользовании, с вас будет незамедлительно списана стандартная стоимость подписки.\n\nМы оставляем за собой право в любое время прервать ваше бесплатное пробное пользование.\n\nНеиспользованная часть бесплатного пробного периода сгорает после приобретения подписки.\n\nЗарегистрировавшись, вы тем самым принимаете настоящие положения и условия."; +"agreement.message" = "После завершения 7-дневного бесплатного пробного периода подписка автоматически продлевается на %@, если не отменить ее по меньшей мере за 24 часа до окончания текущего периода. Плата за продление подписки будет списана со счета вашей учетной записи в течение 24 часов до окончания текущего периода. Для управления подписками, в том числе их отмены, после покупки перейдите в настройки учетной записи в App Store. 7-дневное пробное пользование предлагается каждому пользователю только 1 раз. Неиспользованная часть бесплатного пробного периода сгорает после приобретения подписки. Цена указывается с учетом местных налогов на продажу.\n\nРегистрируясь, вы тем самым принимаете списание с вашего счета сумм в $1 и $2 доллара США."; +"agreement.trials.yearly.plan" = "год"; +"agreement.trials.monthly.plan" = "месяц"; + +"agreement.message.tos" = "Условия использования"; +"agreement.message.privacy" = "Политика конфиденциальности"; + +"getstarted.buttons.buyaccount" = "Приобрести учетную запись"; + +"gdpr.collect.data.title" = "Личная информация, которую мы собираем"; +"gdpr.collect.data.description" = "Адрес эл. почты используется в целях управления учетной записью и защиты от злоупотреблений."; +"gdpr.usage.data.title" = "Использование собираемой нами личной информации"; +"gdpr.usage.data.description" = "Адрес эл. почты используется исключительно для отправки информации о подписке, подтверждений оплаты, переписки с пользователем и отправки акционных предложений Private Internet Access."; +"gdpr.accept.button.title" = "Принять и продолжить"; + +"update.account.email.error" = "Не удалось изменить эл. адрес учетной записи"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings new file mode 100644 index 000000000..520a4ea39 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "ยืนยันการสมัคร"; +"in_progress.message" = "เรากำลังยืนยันการซื้อของคุณกับระบบของเรา กรุณารอสักครู่"; +"in_progress.redeem.message" = "เรากำลังยืนยัน PIN การ์ดของคุณกับระบบของเรา กรุณารอสักครู่"; + +"success.title" = "ซื้อสำเร็จ"; +"success.message_format" = "ขอบคุณที่สมัครสมาชิกกับเรา เราได้ส่งชื่อผู้ใช้และรหัสผ่านไปยังอีเมลของคุณแล้วที่ %@"; +"success.redeem.title" = "คืนบัตรเสร็จสมบูรณ์!"; +"success.redeem.message" = "คุณจะได้รับอีเมลพร้อมชื่อผู้ใช้และรหัสผ่านในไม่ช้า\n\nข้อมูลการล็อกอิน"; +"success.username.caption" = "ชื่อผู้ใช้"; +"success.password.caption" = "รหัสผ่าน"; +"success.submit" = "เริ่มใช้งาน"; + +"failure.vc_title" = "การสมัครล้มเหลว"; +"failure.title" = "สร้างบัญชีผู้ใช้ไม่สำเร็จ"; +"failure.message" = "เราไม่สามารถสร้างบัญชีได้ในขณะนี้ กรุณาลองใหม่อีกครั้งภายหลัง การปิดเปิดแอปใหม่จะเป็นการพยายามสร้างบัญชีใหม่"; +"failure.purchase.sandbox.message" = "ไม่มีระบบสมาชิก Sandbox ที่คุณเลือกอยู่ในการผลิต"; +"failure.redeem.invalid.title" = "PIN การ์ดไม่ถูกต้อง"; +"failure.redeem.invalid.message" = "ดูเหมือนว่าคุณใส่ PIN การ์ดไม่ถูกต้อง กรุณาลองใหม่"; +"failure.redeem.claimed.title" = "บัตรมีการใช้สิทธิ์แล้ว"; +"failure.redeem.claimed.message" = "ดูเหมือนว่าบัตรนี้มีการใช้สิทธิ์แล้วโดยบัญชีอื่น กรุณาลองใส่ PIN อื่น"; +"failure.submit" = "ย้อนกลับ"; + +"unreachable.vc_title" = "ข้อผิดพลาด"; +"unreachable.title" = "อุ๊ปส์!"; +"unreachable.message" = "ไม่พบการเชื่อมต่ออินเทอร์เน็ต กรุณายืนยันว่าคุณมีการเชื่อมต่ออินเทอร์เน็ตแล้วกดลองอีกครั้งด้านล่างนี้\n\nคุณสามารถกลับมาใหม่ในภายหลังเพื่อดำเนินการต่อให้เสร็จ"; +"unreachable.submit" = "ลองใหม่"; + +"purchase.uncredited.alert.message" = "คุณได้ยกเลิกการทำธุรกรรมแล้ว คุณต้องการกู้คืนรายละเอียดบัญชีหรือไม่"; +"purchase.uncredited.alert.button.cancel" = "ยกเลิก"; +"purchase.uncredited.alert.button.recover" = "กู้คืนบัญชี"; + +"purchase.trials.intro" = "เริ่มทดลองใช้ฟรี 7 วัน"; +"purchase.trials.price.after" = "จากนั้น %@"; +"purchase.trials.money.back" = "รับประกันการคืนเงินภายใน 30 วัน"; +"purchase.trials.1year.protection" = "การป้องกันข้อมูลประจำตัวและความเป็นส่วนตัว 1 ปี"; +"purchase.trials.anonymous" = "เรียกดูโดยไม่ระบุชื่อและซ่อน ip ของคุณ"; +"purchase.trials.devices" = "รับรองอุปกรณ์ 10 เครื่องในเวลาเดียวกัน"; +"purchase.trials.devices.description" = "ปกป้องตัวคุณบนอุปกรณ์ถึง 10 เครื่องในเวลาเดียวกัน"; +"purchase.trials.region" = "เชื่อมต่อไปยังภูมิภาคใดก็ตามได้อย่างง่ายดาย"; +"purchase.trials.servers" = "กว่า 3300 เซิร์ฟเวอร์ใน 32 ประเทศ"; +"purchase.trials.start" = "เริ่มการเป็นสมาชิก"; +"purchase.trials.all.plans" = "ดูแผนที่มีทั้งหมด"; + +"purchase.subscribe.now" = "สมัครสมาชิกตอนนี้"; + +// WALKTHROUGH + +"walkthrough.action.next" = "ถัดไป"; +"walkthrough.action.done" = "เสร็จสิ้น"; +"walkthrough.action.skip" = "ข้าม"; + +"walkthrough.page.1.title" = "รับรองอุปกรณ์ 10 เครื่องในคราวเดียว"; +"walkthrough.page.1.description" = "ปกป้องตัวคุณบนอุปกรณ์ถึง 10 เครื่องในเวลาเดียวกัน"; +"walkthrough.page.2.title" = "เชื่อมต่อไปยังภูมิภาคใดก็ตามได้อย่างง่ายดาย"; +"walkthrough.page.2.description" = "ด้วยเซิร์ฟเวอร์ที่มีอยู่ทั่วโลก คุณจะได้รับความคุ้มครองตลอดเวลา"; +"walkthrough.page.3.title" = "ปกป้องตัวคุณจากโฆษณา"; +"walkthrough.page.3.description" = "การเปิดใช้งานตัวปิดกั้นเนื้อหาของเราจะเป็นการป้องกันไม่ให้แสดงโฆษณาใน Safari"; + +"share.data.buttons.accept" = "ยอมรับ"; +"share.data.buttons.noThanks" = "ไม่ล่ะ ขอบคุณ"; +"share.data.buttons.readMore" = "อ่านเพิ่มเติม"; +"share.data.text.title" = "โปรดช่วยเราปรับปรุงบริการของเรา"; +"share.data.text.description" = "เพื่อช่วยให้เรามั่นใจในประสิทธิภาพการเชื่อมต่อของบริการของเรา คุณสามารถแชร์สถิติการเชื่อมต่อของคุณกับเราโดยไม่ระบุชื่อ รายงานเหล่านี้ไม่รวมข้อมูลส่วนบุคคลที่สามารถระบุตัวตนได้"; +"share.data.text.footer" = "คุณสามารถควบคุมสิ่งนี้ได้จากการตั้งค่าของคุณ"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/th.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/th.lproj/UI.strings new file mode 100644 index 000000000..3069ecff4 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/th.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "เวอร์ชั่น %@ (%@)"; +"global.close" = "ปิด"; +"global.ok" = "ตกลง"; +"global.cancel" = "ยกเลิก"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings new file mode 100644 index 000000000..637de14e0 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "ลงชื่อเข้าใช้บัญชีของคุณ"; +"login.username.placeholder" = "ชื่อผู้ใช้ (p1234567)"; +"login.password.placeholder" = "รหัสผ่าน"; +"login.submit" = "เข้าสู่ระบบ"; +"login.restore.button" = "ยังไม่ได้รับรายละเอียดบัญชีหรือ"; +"login.error.title" = "เข้าสู่ระบบ"; +"login.error.validation" = "คุณต้องกรอกชื่อผู้ใช้และรหัสผ่าน"; +"login.error.unauthorized" = "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "เข้าสู่ระบบโดยใช้ใบเสร็จรับเงิน"; +"login.magic.link.title" = "เข้าสู่ระบบโดยใช้ลิงก์อีเมลวิเศษ"; +"login.magic.link.response" = "โปรดตรวจสอบอีเมลของคุณเพื่อดูลิงค์สำหรับเข้าสู่ระบบ"; +"login.magic.link.send" = "ส่งลิงก์"; +"login.magic.link.invalid.email" = "อีเมลไม่ถูกต้อง กรุณาลองอีกครั้ง"; + +"purchase.title" = "เลือกแผน VPN"; +"purchase.subtitle" = "รับประกันการคืนเงินภายใน 30 วัน"; +"purchase.email.placeholder" = "อีเมลแอดเดรส"; +"purchase.continue" = "ดำเนินการต่อ"; +"purchase.login.footer" = "มีบัญชีแล้วหรือยัง"; +"purchase.login.button" = "ลงชื่อเข้าใช้"; +"purchase.error.title" = "ซื้อ"; +"purchase.error.validation" = "คุณต้องใส่ที่อยู่อีเมล"; +"purchase.error.connectivity.title" = "ความล้มเหลวในการเชื่อมต่อ"; +"purchase.error.connectivity.description" = "เราไม่สามารถเข้าถึง Private Internet Access ซึ่งอาจเป็นเพราะอินเทอร์เน็ตไม่เสถียรหรือบริการของเราถูกบล็อกในประเทศของคุณ"; +"purchase.confirm.form.email" = "กรุณากรอกอีเมลของคุณ"; +"purchase.confirm.plan" = "คุณกำลังซื้อแผน %@"; +"purchase.email.why" = "โปรดแจ้งอีเมลสำหรับส่งชื่อผู้ใช้และรหัสผ่านของคุณ"; +"purchase.submit" = "ส่ง"; +"purchase.or" = "หรือ"; + +"upgrade.header" = "ยินดีต้อนรับกลับมา!"; +"upgrade.title" = "หากต้องการใช้ Private Internet Access คุณจะต้องต่ออายุสมาชิกของคุณ"; +"upgrade.renew.now" = "ต่ออายุตอนนี้"; + + + +"redeem.title" = "ใช้สิทธิ์บัตรของขวัญ"; +"redeem.subtitle" = "พิมพ์ที่อยู่อีเมลของคุณและ PIN %lu หลักจากบัตรของขวัญหรือบัตรทดลองด้านล่าง"; +"redeem.email.placeholder" = "ที่อยู่อีเมล"; +"redeem.submit" = "ส่ง"; +"redeem.error.title" = "ใช้สิทธิ์"; +"redeem.error.code" = "รหัสต้องประกอบด้วยตัวเลข %lu หลัก"; +"redeem.error.allfields" = "กรุณากรอกอีเมลและ PIN"; +"redeem.accessibility.back" = "กลับ"; +"redeem.giftcard.placeholder" = "PIN บัตรของขวัญ"; + +"plan.monthly.title" = "รายเดือน"; +"plan.yearly.title" = "รายปี"; +"plan.yearly.detail_format" = "%@%@ ต่อปี"; +"plan.price_format" = "%@/เดือน"; +"plan.best_value" = "คุ้มค่าที่สุด"; +"plan.accessibility.per_month" = "ต่อเดือน"; + +"restore.title" = "คืนค่าการซื้อยังไม่ได้คิดเครดิต"; +"restore.subtitle" = "หากคุณทำการซื้อแผนผ่านแอพนี้และยังไม่ได้รับข้อมูลประจำตัว คุณสามารถส่งอีกครั้งได้จากที่นี่ คุณจะไม่ถูกเรียกเก็บเงินซ้ำอีกครั้งในกระบวนการนี้"; +"restore.email.placeholder" = "อีเมลแอดเดรส"; +"restore.submit" = "ยืนยัน"; + +"iap.error.message.unavailable" = "ไม่พบเซิร์ฟเวอร์แอปเปิ้ลในขณะนี้ โปรดลองใหม่ภายหลัง"; +"iap.error.title" = "ข้อผิดพลาด"; + +"agreement.trials.title" = "ข้อกำหนดและเงื่อนไขการทดลองใช้ฟรี"; +"agreement.trials.message" = "ยอดชำระเงินจะถูกหักจากบัญชี Apple ID ของคุณเมื่อมีการยืนยันคำสั่งซื้อ ระบบจะต่ออายุสมาชิกโดยอัตโนมัติเว้นแต่จะมีการยกเลิกล่วงหน้าอย่างน้อย 24 ชั่วโมงก่อนที่จะสิ้นสุดรอบใช้งานปัจจุบัน บัญชีของคุณจะถูกเรียกเก็บเงินค่าต่ออายุสมาชิกภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบใช้งานปัจจุบัน คุณสามารถจัดการและยกเลิกการเป็นสมาชิกได้โดยไปที่การตั้งค่าบัญชีใน App Store หลังจากซื้อแล้ว\n\nบางระบบสมาชิกแบบชำระเงินอาจเสนอให้คุณทดลองใช้ฟรีก่อนที่จะเรียกเก็บเงินผ่านช่องทางการชำระเงินที่คุณเลือกไว้ หากคุณตัดสินใจที่จะยกเลิกการสมัครสมาชิกแบบชำระเงินก่อนที่เราจะเริ่มเรียกเก็บเงินผ่านช่องทางการชำระเงินที่เลือกไว้ ให้ทำการยกเลิกสมาชิกล่วงหน้าอย่างน้อย 24 ชั่วโมงก่อนที่ช่วงทดลองใช้ฟรีจะสิ้นสุดลง\n\nสามารถทดลองใช้ฟรีเฉพาะผู้ใช้ใหม่เท่านั้นและขึ้นอยู่กับดุลยพินิจของเราแต่เพียงผู้เดียว และหากคุณพยายามที่จะสมัครเพื่อทดลองใช้ฟรีซ้ำอีก คุณจะถูกเรียกเก็บค่าธรรมเนียมการสมัครสมาชิกตามมาตรฐานทันที\n\nเราขอสงวนสิทธิ์ในการเพิกถอนสิทธิ์ทดลองใช้ฟรีของคุณได้ตลอดเวลา\n\nส่วนที่ไม่ได้ใช้งานของช่วงทดลองใช้ฟรีจะถูกหักทิ้งเมื่อมีการสมัครสมาชิก\n\nการสมัครสมาชิกถือว่าเป็นการยอมรับข้อกำหนดและเงื่อนไขนี้"; +"agreement.message" = "หลังจากทดลองใช้ฟรี 7 วัน ระบบจะต่ออายุสมาชิกนี้โดยอัตโนมัติในราคา %@ เว้นแต่จะมีการยกเลิกล่วงหน้าอย่างน้อย 24 ชั่วโมงก่อนที่จะสิ้นสุดรอบใช้งานปัจจุบัน บัญชี Apple ID ของคุณจะถูกเรียกเก็บเงินค่าต่ออายุสมาชิกภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบใช้งานปัจจุบัน คุณสามารถจัดการและยกเลิกการเป็นสมาชิกได้โดยไปที่การตั้งค่าบัญชีใน App Store หลังจากซื้อแล้ว จำกัดสิทธิ์การทดลองใช้ฟรี 7 วัน เพียง 1 สิทธิ์ต่อผู้ใช้หนึ่งราย ส่วนที่ไม่ได้ใช้งานของช่วงทดลองใช้ฟรีหากมีให้จะถูกริบเมื่อผู้ใช้ซื้อการสมัครสมาชิก ราคาทั้งหมดรวมภาษีการขายในท้องที่\n\nการลงทะเบียนจะถือว่าคุณยินยอมตาม $1 และ $2"; +"agreement.trials.yearly.plan" = "ปี"; +"agreement.trials.monthly.plan" = "เดือน"; + +"agreement.message.tos" = "ข้อตกลงการใช้บริการ"; +"agreement.message.privacy" = "นโยบายความเป็นส่วนตัว"; + +"getstarted.buttons.buyaccount" = "ซื้อบัญชี"; + +"gdpr.collect.data.title" = "ข้อมูลส่วนบุคคลที่เรารวบรวม"; +"gdpr.collect.data.description" = "อีเมลเพื่อจุดประสงค์ในการจัดการและการป้องกันบัญชีจากการใช้งานในทางที่ผิด"; +"gdpr.usage.data.title" = "การใช้ข้อมูลส่วนบุคคลที่เรารวบรวม"; +"gdpr.usage.data.description" = "ที่อยู่อีเมลใช้ในการส่งข้อมูลการสมัครสมาชิก การยืนยันการชำระเงิน การติดต่อกับลูกค้า และข้อเสนอส่งเสริมการขาย Private Internet Access เท่านั้น"; +"gdpr.accept.button.title" = "ยอมรับและดำเนินการต่อ"; + +"update.account.email.error" = "ไม่สามารถแก้ไขอีเมลบัญชีได้"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings new file mode 100644 index 000000000..36d6ad53a --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings @@ -0,0 +1,166 @@ +/* (No Comment) */ +"failure.message" = "Şu anda hesap oluşturamıyoruz.\nLütfen daha sonra tekrar deneyin.\n\nUygulama yeniden açıldığından hesap oluşturma tekrar denenecektir."; + +/* (No Comment) */ +"failure.purchase.sandbox.message" = "Seçilen Sandbox aboneliği üretim ortamında mevcut değil."; + +/* (No Comment) */ +"failure.redeem.claimed.message" = "Bu kart önceden başka bir hesap tarafından talep edilmiş. Farklı bir PIN girmeyi deneyebilirsiniz."; + +/* (No Comment) */ +"failure.redeem.claimed.title" = "Kart önceden talep edilmiş"; + +/* (No Comment) */ +"failure.redeem.invalid.message" = "Görünüşe bakılırsa geçersiz bir kart PIN'i girdiniz. Lütfen tekrar deneyin."; + +/* (No Comment) */ +"failure.redeem.invalid.title" = "Geçersiz kart PIN'i"; + +/* (No Comment) */ +"failure.submit" = "GERİ DÖN"; + +/* (No Comment) */ +"failure.title" = "Hesap Oluşturma Hatası"; + +/* (No Comment) */ +"failure.vc_title" = "Kaydolma başarısız oldu"; + +/* (No Comment) */ +"in_progress.message" = "Sistemimizle satın alım işleminizi onaylıyoruz. Biraz zaman alabilir; lütfen bekleyin."; + +/* (No Comment) */ +"in_progress.redeem.message" = "Kart PIN'inizi sistemimizde onaylıyoruz. Bu biraz zaman alabilir, lütfen bekleyin."; + +/* Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. */ +"in_progress.title" = "Kaydolmayı onayla"; + +/* (No Comment) */ +"purchase.subscribe.now" = "Hemen abone ol"; + +/* (No Comment) */ +"purchase.trials.1year.protection" = "1 yıllık gizlilik ve kimlik koruması"; + +/* (No Comment) */ +"purchase.trials.all.plans" = "Tüm mevcut planlara bakın"; + +/* (No Comment) */ +"purchase.trials.anonymous" = "IP'nizi gizleyerek İnternet'te isimsiz gezinin."; + +/* (No Comment) */ +"purchase.trials.devices" = "Aynı anda 10 cihaz desteği"; + +/* (No Comment) */ +"purchase.trials.devices.description" = "Aynı anda 10 cihazda kendinizi koruyun."; + +/* (No Comment) */ +"purchase.trials.intro" = "7 günlük ücretsiz deneme sürenizi başlatın"; + +/* (No Comment) */ +"purchase.trials.money.back" = "30 günlük para iade garantisi"; + +/* (No Comment) */ +"purchase.trials.price.after" = "Ardından %@"; + +/* (No Comment) */ +"purchase.trials.region" = "Tüm bölgelere kolayca bağlanın"; + +/* (No Comment) */ +"purchase.trials.servers" = "32 ülkede en az 3.300 sunucu"; + +/* (No Comment) */ +"purchase.trials.start" = "Aboneliği başlat"; + +/* (No Comment) */ +"purchase.uncredited.alert.button.cancel" = "İptal"; + +/* (No Comment) */ +"purchase.uncredited.alert.button.recover" = "Hesabı kurtar"; + +/* (No Comment) */ +"purchase.uncredited.alert.message" = "Hesaba yansıtılmamış olan işlemleriniz var. Hesap bilgilerinizi kurtarmak ister misiniz?"; + +/* (No Comment) */ +"share.data.buttons.accept" = "Kabul Et"; + +/* (No Comment) */ +"share.data.buttons.noThanks" = "Hayır, teşekkürler"; + +/* (No Comment) */ +"share.data.buttons.readMore" = "Devamını oku"; + +/* (No Comment) */ +"share.data.readMore.text.description" = "Bu asgari bilgi, potansiyel bağlantı sorunlarını tanımlayıp düzeltmemize yardımcı olur. Bu bilgiyi paylaşmak için onay verilmesi ve varsayılan olarak kapalı olduğu için elle etkinleştirilmesi gerektiğini dikkate alın.\n\nŞu olaylarla ilgili bilgi toplayacağız:\n\n - Bağlantı Denemesi\n - Bağlantı İptal Edildi\n - Bağlantı Kuruldu\n\nTüm bu olaylar için şu bilgileri toplayacağız:\n - Platform\n - Uygulama sürümü\n - Uygulama türü (ön sürüm olup olmadığı)\n - Kullanılan protokol\n - Bağlantı kaynağı (manuel ya da otomasyon ile)\n\nTüm olaylarda rastgele oluşturulan eşsiz bir kimlik yer alacak. Bu kimlik kullanıcı hesabınızla bağlantılı değildir. Bu eşsiz kimlik, gizliliğin korunması açısından günlük olarak üretilir.\n\nKontrol daima sizde olacak. Ayarlardan hangi verileri topladığımızı görebilir ve bunu istediğiniz zaman kapatabilirsiniz."; + +/* (No Comment) */ +"share.data.text.description" = "Hizmetimizin bağlantı performansını korumamıza yardımcı olmak için bağlantı istatistiklerinizi isimsiz olarak bizimle paylaşabilirsiniz. Bu raporlarda kişiyi tanımlayabilecek herhangi bir bilgi yer almaz."; + +/* (No Comment) */ +"share.data.text.footer" = "Bunu istediğiniz zaman ayarlarınızdan kontrol edebilirsiniz"; + +/* (No Comment) */ +"share.data.text.title" = "Lütfen hizmetimizi geliştirmemize yardım edin"; + +/* (No Comment) */ +"success.message_format" = "Bize kayıt olduğunuz için teşekkürler. Hesap kullanıcı adı ve parolanızı %@ e-posta adresinize gönderdik"; + +/* (No Comment) */ +"success.password.caption" = "Şifre"; + +/* (No Comment) */ +"success.redeem.message" = "Kısa süre içinde kullanıcı adınızı ve şifrenizi içeren bir e-posta alacaksınız.\n\nGiriş bilgileriniz"; + +/* (No Comment) */ +"success.redeem.title" = "Kart başarıyla kullanıldı"; + +/* (No Comment) */ +"success.submit" = "Başlarken"; + +/* (No Comment) */ +"success.title" = "Satın Alma Tamamlandı"; + +/* (No Comment) */ +"success.username.caption" = "Kullanıcı Adı"; + +/* (No Comment) */ +"unreachable.message" = "İnternet bağlantısı yok. Lütfen İnternet bağlantınız olup olmadığını kontrol edin ve tekrar aşağıya tıklamayı deneyin.\n\nİşlemi bitirmek için uygulamaya daha sonra tekrar gelebilirsiniz."; + +/* (No Comment) */ +"unreachable.submit" = "TEKRAR DENE"; + +/* (No Comment) */ +"unreachable.title" = "Heeey!"; + +/* (No Comment) */ +"unreachable.vc_title" = "Hata"; + +/* (No Comment) */ +"walkthrough.action.done" = "BİTTİ"; + +/* WALKTHROUGH */ +"walkthrough.action.next" = "İLERİ"; + +/* (No Comment) */ +"walkthrough.action.skip" = "ATLA"; + +/* (No Comment) */ +"walkthrough.page.1.description" = "Aynı anda 10 cihazda koruma sağlayın."; + +/* (No Comment) */ +"walkthrough.page.1.title" = "Aynı anda 10 cihazı destekler"; + +/* (No Comment) */ +"walkthrough.page.2.description" = "Dünya çapındaki sunucularla daima koruma altındasınız."; + +/* (No Comment) */ +"walkthrough.page.2.title" = "Herhangi bir bölgeye kolayca bağlanın"; + +/* (No Comment) */ +"walkthrough.page.3.description" = "İçerik Engelleyicimizi etkinleştirdiğinizde Safari'de reklamların gösterilmesi engellenir."; + +/* (No Comment) */ +"walkthrough.page.3.title" = "Kendinizi reklamlardan koruyun"; + diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings new file mode 100644 index 000000000..fc6795eb9 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings @@ -0,0 +1,12 @@ +/* (No Comment) */ +"global.cancel" = "İptal"; + +/* (No Comment) */ +"global.close" = "Kapat"; + +/* (No Comment) */ +"global.ok" = "Tamam"; + +/* (No Comment) */ +"global.version.format" = "Sürüm %@ (%@)"; + diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings new file mode 100644 index 000000000..49d7ab5ca --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings @@ -0,0 +1,205 @@ +/* (No Comment) */ +"agreement.message" = "Bu abonelik, deneme süresinin sonuna en az 24 saat kalana dek iptal edilmezse, otomatik olarak %@ karşılığında yenilenir. Deneme süresinin sonuna 24 saat kaldıktan sonra, Apple Kimliğinizin hesabından yenileme ücreti alınır. Satın alım işleminden sonra App Store hesap ayarlarına giderek abonelik ayarlarınızı değiştirebilir ve aboneliklerinizi iptal edebilirsiniz. 7 günlük deneme süresi, her kullanıcı için bir tane 7 günlük deneme süresi hakkı ile sınırlıdır. Kullanıcı bir abonelik satın aldığında, teklif edilmişse, ücretsiz deneme süresinin kullanılmayan herhangi bir kısmı geçerliliğini yitirir. Tüm fiyatlara uygulanabilir yerel satış vergileri dahildir.\n\nKaydolduğunuzda, $1 ile $2 unsurlarını kabul etmiş olursunuz."; + +/* (No Comment) */ +"agreement.message.privacy" = "Gizlilik Politikası"; + +/* (No Comment) */ +"agreement.message.tos" = "Hizmet Koşulları"; + +/* (No Comment) */ +"agreement.trials.message" = "Satın alım onaylandıktan sonra, ödeme ücreti, Apple Kimliği hesabınızdan alınır. Mevcut dönemin sonuna en az 24 saat kalana dek iptal edilmezse, abonelik otomatik olarak yenilenir. Mevcut dönemin sonuna 24 saat kaldıktan sonra hesabınızdan yenileme ücreti alınır. Satın alım işleminden sonra App Store'daki hesap ayarlarınıza giderek abonelik ayarlarınızı değiştirebilir ve aboneliğinizi iptal edebilirsiniz.\n\nBelirli Ücretli Abonelik planlarında, seçtiğiniz ödeme yöntemiyle ücret alınmadan önce, bir ücretsiz kullanım süresi sunulabilir. Seçtiğiniz ödeme yöntemiyle sizden ücret almaya başlamamızdan önce Ücretli Aboneliğinizi iptal etmek isterseniz, ücretsiz kullanım süresinin sonuna en az 24 saat kalana dek aboneliğinizi iptal etmelisiniz.\n\nÜcretsiz deneme süresinden sadece yeni kullanıcılar faydalanabilir ve bu tamamen bizim takdirimizdedir. Tekrar kaydolarak bir ücretsiz deneme süresi daha almaya çalışırsanız, standart Abonelik Ücreti anında hesabınızdan düşülür.\n\nÜcretsiz deneme sürenizi istediğimiz zaman iptal etme hakkına sahibiz.\n\nBir abonelik satın aldığınızda, ücretsiz kullanım sürenizin kullanılmayan kısmını yitirirsiniz.\n\nKaydolduğunuzda bu şart ve koşulları kabul etmiş olursunuz."; + +/* (No Comment) */ +"agreement.trials.monthly.plan" = "ay"; + +/* (No Comment) */ +"agreement.trials.title" = "Ücretsiz deneme süresi şart ve koşulları"; + +/* (No Comment) */ +"agreement.trials.yearly.plan" = "yıl"; + +/* (No Comment) */ +"gdpr.accept.button.title" = "Kabul edip devam et"; + +/* (No Comment) */ +"gdpr.collect.data.description" = "Hesap yönetimi ve ihlalden koruma için E-posta Adresi."; + +/* (No Comment) */ +"gdpr.collect.data.title" = "Topladığımız kişisel bilgiler"; + +/* (No Comment) */ +"gdpr.usage.data.description" = "E-posta adresi sadece abonelik bilgilerinin, ödeme onaylarının, müşteri iletişim unsurlarının ve Private Internet Access'in promosyonel tekliflerinin gönderilmesi için kullanılır."; + +/* (No Comment) */ +"gdpr.usage.data.title" = "Tarafımızca toplanan kişisel bilgilerin kullanım şekilleri"; + +/* (No Comment) */ +"getstarted.buttons.buyaccount" = "Hesap satın al"; + +/* (No Comment) */ +"iap.error.message.unavailable" = "Apple sunucuları şu anda kullanılamıyor. Lütfen daha sonra tekrar deneyin."; + +/* (No Comment) */ +"iap.error.title" = "Hata"; + +/* (No Comment) */ +"login.error.throttled" = "Bu kullanıcı adı ile çok fazla kez yanlış giriş yapıldı. Lütfen daha sonra tekrar deneyin."; + +/* (No Comment) */ +"login.error.title" = "Giriş yap"; + +/* (No Comment) */ +"login.error.unauthorized" = "Kullanıcı adınız ya da şifreniz hatalı."; + +/* (No Comment) */ +"login.error.validation" = "Bir kullanıcı adı ve şifre girmelisiniz."; + +/* (No Comment) */ +"login.magic.link.invalid.email" = "E-posta adresi geçersiz. Lütfen tekrar deneyin."; + +/* (No Comment) */ +"login.magic.link.response" = "Giriş linkini bulmak için lütfen e-postalarınıza bakın."; + +/* (No Comment) */ +"login.magic.link.send" = "Link Gönder"; + +/* (No Comment) */ +"login.magic.link.title" = "Sihirli e-posta linki ile giriş yap"; + +/* (No Comment) */ +"login.password.placeholder" = "Şifre"; + +/* (No Comment) */ +"login.receipt.button" = "Satın alım faturasıyla giriş yapın"; + +/* (No Comment) */ +"login.restore.button" = "Hesap bilgilerinizi almadınız mı?"; + +/* (No Comment) */ +"login.submit" = "GİRİŞ YAP"; + +/* Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. */ +"login.title" = "Hesabınıza giriş yapın"; + +/* (No Comment) */ +"login.username.placeholder" = "Kullanıcı Adı (p1234567)"; + +/* (No Comment) */ +"plan.accessibility.per_month" = "aylık"; + +/* (No Comment) */ +"plan.best_value" = "En iyi fiyat"; + +/* (No Comment) */ +"plan.monthly.title" = "Aylık"; + +/* (No Comment) */ +"plan.price_format" = "%@/ay"; + +/* (No Comment) */ +"plan.yearly.detail_format" = "Yılda %@%@"; + +/* (No Comment) */ +"plan.yearly.title" = "Yıllık"; + +/* (No Comment) */ +"purchase.confirm.form.email" = "E-posta adresinizi girin"; + +/* (No Comment) */ +"purchase.confirm.plan" = "%@ planını satın alıyorsunuz"; + +/* (No Comment) */ +"purchase.continue" = "Devam et"; + +/* (No Comment) */ +"purchase.email.placeholder" = "E-posta adresi"; + +/* (No Comment) */ +"purchase.email.why" = "Kullanıcı adınızla şifrenizi gönderebilmemiz için e-posta adresinize ihtiyacımız var."; + +/* (No Comment) */ +"purchase.error.connectivity.description" = "Özel İnternet Erişimi'ne ulaşamıyoruz. Bu zayıf internet yüzünden olabilir veya hizmetimiz ülkenizde engelleniyor."; + +/* (No Comment) */ +"purchase.error.connectivity.title" = "Bağlantı Hatası"; + +/* (No Comment) */ +"purchase.error.title" = "Satın Al"; + +/* (No Comment) */ +"purchase.error.validation" = "Bir e-posta adresi girmeniz gerekiyor."; + +/* (No Comment) */ +"purchase.login.button" = "Giriş yapın"; + +/* (No Comment) */ +"purchase.login.footer" = "Hesabınız var mı?"; + +/* (No Comment) */ +"purchase.or" = "veya"; + +/* (No Comment) */ +"purchase.submit" = "Gönder"; + +/* (No Comment) */ +"purchase.subtitle" = "30 günlük para iade garantisi"; + +/* (No Comment) */ +"purchase.title" = "Bir VPN planı seçin"; + +/* (No Comment) */ +"redeem.accessibility.back" = "Geri"; + +/* (No Comment) */ +"redeem.email.placeholder" = "E-posta adresi"; + +/* (No Comment) */ +"redeem.error.allfields" = "Lütfen e-posta adresinizi ve kart PIN numaranızı girin."; + +/* (No Comment) */ +"redeem.error.code" = "Kod, %lu sayısal haneden oluşmalıdır."; + +/* (No Comment) */ +"redeem.error.title" = "Kullan"; + +/* (No Comment) */ +"redeem.giftcard.placeholder" = "Hediye kartı ve PIN"; + +/* (No Comment) */ +"redeem.submit" = "Gönder"; + +/* (No Comment) */ +"redeem.subtitle" = "E-posta adresinizi ve hediye kartınızdaki ya da deneme kartınızdaki %lu haneli PIN'i aşağıya girin."; + +/* (No Comment) */ +"redeem.title" = "Hediye kartını kullan"; + +/* (No Comment) */ +"restore.email.placeholder" = "E-posta adresi"; + +/* (No Comment) */ +"restore.submit" = "ONAYLA"; + +/* (No Comment) */ +"restore.subtitle" = "Bu uygulamadan bir plan satın aldıktan sonra hesap bilgilerinizi alamadıysanız, onları buradan tekrar gönderebilirsiniz. Bu işlem esnasında sizden ücret alınmayacak."; + +/* (No Comment) */ +"restore.title" = "Bilgileri gönderilmeyen satın alma işlemini tekrarlayın"; + +/* (No Comment) */ +"update.account.email.error" = "Hesap e-posta adresi değiştirilemedi"; + +/* (No Comment) */ +"upgrade.header" = "Tekrar Hoş Geldiniz!"; + +/* (No Comment) */ +"upgrade.renew.now" = "Hemen yenileyin"; + +/* (No Comment) */ +"upgrade.title" = "Private Internet Access kullanabilmek için aboneliğinizi yenilemeniz gerekiyor."; + diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings new file mode 100644 index 000000000..2f4afbb78 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "确认注册"; +"in_progress.message" = "我们正在确认您在我们系统中的购买。这可能需要一点时间,请耐心等待。"; +"in_progress.redeem.message" = "我们正在通过系统确认您的卡片PIN。这可能需要一些时间,请耐心等待。"; + +"success.title" = "购买完成"; +"success.message_format" = "感谢注册。我们已将您的用户名和密码发送至您的电子邮箱:%@"; +"success.redeem.title" = "卡片兑换成功"; +"success.redeem.message" = "您将很快收到一封电子邮件,记有您的用户名和密码。\n\n您的登录详情"; +"success.username.caption" = "用户名"; +"success.password.caption" = "密码"; +"success.submit" = "开始体验"; + +"failure.vc_title" = "注册失败"; +"failure.title" = "账户创建失败"; +"failure.message" = "我们现在无法创建账号。\n请稍后再试。\n\n重新打开本应用将会再次尝试创建账号。"; +"failure.purchase.sandbox.message" = "所选的沙盒订阅不适用于生产"; +"failure.redeem.invalid.title" = "卡片PIN无效"; +"failure.redeem.invalid.message" = "您输入的卡片PIN似乎无效。请重试。"; +"failure.redeem.claimed.title" = "卡片已使用"; +"failure.redeem.claimed.message" = "此卡片似乎已被另一个账号使用。您可尝试输入另一个PIN。"; +"failure.submit" = "返回"; + +"unreachable.vc_title" = "错误"; +"unreachable.title" = "糟糕!"; +"unreachable.message" = "未找到网络连接。请确认您已接入网络,然后点击下面的重试。\n\n您可在稍后再回到本应用完成该操作。"; +"unreachable.submit" = "重试"; + +"purchase.uncredited.alert.message" = "你有未入账的的交易。要恢复您的账户详情吗?"; +"purchase.uncredited.alert.button.cancel" = "取消"; +"purchase.uncredited.alert.button.recover" = "恢复账户"; + +"purchase.trials.intro" = "开始 7 天免费试用"; +"purchase.trials.price.after" = "然后 %@"; +"purchase.trials.money.back" = "7 天退款保证"; +"purchase.trials.1year.protection" = "1 年隐私和身份保护"; +"purchase.trials.anonymous" = "匿名浏览并隐藏您的 IP。"; +"purchase.trials.devices" = "一次支持 10 台设备"; +"purchase.trials.devices.description" = "一次在多达 10 台设备上保护自己。"; +"purchase.trials.region" = "轻松连接到任何地区"; +"purchase.trials.servers" = "在 32 个国家h地区拥有超过 3300 台服务器"; +"purchase.trials.start" = "开始订阅"; +"purchase.trials.all.plans" = "查看所有可用套餐"; + +"purchase.subscribe.now" = "立即订阅"; + +// WALKTHROUGH + +"walkthrough.action.next" = "下一个"; +"walkthrough.action.done" = "完成"; +"walkthrough.action.skip" = "跳过"; + +"walkthrough.page.1.title" = "一次支持 10 台设备"; +"walkthrough.page.1.description" = "一次在多达 10 台设备上保护自己。"; +"walkthrough.page.2.title" = "轻松连接到任何地区"; +"walkthrough.page.2.description" = "服务器遍布世界各地,您始终受到保护。"; +"walkthrough.page.3.title" = "让自己远离广告"; +"walkthrough.page.3.description" = "启用内容拦截器以防止 Safari 中出现广告。"; + +"share.data.buttons.accept" = "接受"; +"share.data.buttons.noThanks" = "不用,谢谢"; +"share.data.buttons.readMore" = "阅读更多"; +"share.data.text.title" = "请帮助我们改进服务"; +"share.data.text.description" = "为了帮助我们保持服务的连接性能,您可以匿名与我们共享您的连接统计数据。这些报告不包括任何可识别个人身份的信息。"; +"share.data.text.footer" = "您始终可以从设置中进行控制"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings new file mode 100644 index 000000000..e6f012399 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "版本 %@ (%@)"; +"global.close" = "关闭"; +"global.ok" = "确定"; +"global.cancel" = "取消"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings new file mode 100644 index 000000000..8d5c7e113 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "登录到您的帐户"; +"login.username.placeholder" = "用户名 (p1234567)"; +"login.password.placeholder" = "密码"; +"login.submit" = "登录"; +"login.restore.button" = "没有收到账户详情?"; +"login.error.title" = "登录"; +"login.error.validation" = "您必须输入用户名和密码。"; +"login.error.unauthorized" = "您的用户名或密码不正确。"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "使用购买收据登录"; +"login.magic.link.title" = "使用魔法电子邮件链接登录"; +"login.magic.link.response" = "请检查您的电子邮件,以查找登录链接。"; +"login.magic.link.send" = "发送链接"; +"login.magic.link.invalid.email" = "电子邮箱乎无效。请重试。"; + +"purchase.title" = "选择 VPN 套餐"; +"purchase.subtitle" = "7 天退款保证"; +"purchase.email.placeholder" = "电子邮件地址"; +"purchase.continue" = "继续"; +"purchase.login.footer" = "已有帐号?"; +"purchase.login.button" = "登录"; +"purchase.error.title" = "购买"; +"purchase.error.validation" = "您必须输入一个电子邮箱地址。"; +"purchase.error.connectivity.title" = "连接失败"; +"purchase.error.connectivity.description" = "我们无法接入Private Internet Access。原因可能是互联网连接不良或者我们的服务在您的国家遭到屏蔽。"; +"purchase.confirm.form.email" = "请输入您的电子邮件地址"; +"purchase.confirm.plan" = "您正在购买 %@ 套餐"; +"purchase.email.why" = "我们需要您的电子邮件以发送您的用户名和密码。"; +"purchase.submit" = "提交"; +"purchase.or" = "或"; + +"upgrade.header" = "欢迎回来!"; +"upgrade.title" = "您需要续订才能使用 Private Internet Access。"; +"upgrade.renew.now" = "立即续订"; + + + +"redeem.title" = "兑换礼品卡"; +"redeem.subtitle" = "请输入您的电子邮箱地址以及礼品卡或试用卡上的%lu位数字PIN。"; +"redeem.email.placeholder" = "邮箱地址"; +"redeem.submit" = "提交"; +"redeem.error.title" = "兑换"; +"redeem.error.code" = "PIN码必须包含%lu个数字。"; +"redeem.error.allfields" = "请输入您的电子邮件和卡片 PIN 码。"; +"redeem.accessibility.back" = "返回"; +"redeem.giftcard.placeholder" = "礼品卡 PIN"; + +"plan.monthly.title" = "每月"; +"plan.yearly.title" = "每年"; +"plan.yearly.detail_format" = "%@%@/每年"; +"plan.price_format" = "%@/每月"; +"plan.best_value" = "最超值"; +"plan.accessibility.per_month" = "每月"; + +"restore.title" = "恢复未入账的购买"; +"restore.subtitle" = "如果您通过此 app 购买了套餐,但没有收到凭据,可以从这里重新发送。在此过程中您不会被收费。"; +"restore.email.placeholder" = "电子邮件地址"; +"restore.submit" = "确认"; + +"iap.error.message.unavailable" = "Apple 服务器目前不可用。请稍后重试。"; +"iap.error.title" = "错误"; + +"agreement.trials.title" = "免费试用条款和条件"; +"agreement.trials.message" = "确认购买后,将从您的 Apple ID 账户中收取款项。除非在当前使用期结束前至少提前 24 小时取消,否则会自动续订。您的账户将在当前使用期结束前 24 小时内收取续订费用。您可以在购买后前往 App Store 上的账户设置来管理和取消订阅。\n\n某些“付费订阅”可能会在向您收取款项之前先提供免费试用。如果您在我们开始收取款项之前决定取消订阅“付费订阅”,请在免费试用结束前至少提前 24 小时取消订阅。\n\n免费试用仅适用于新用户,并由我们自行决定,如果您尝试注册额外的免费试用,您将被立即收取标准订阅费。\n\n我们有权随时撤销您的免费试用。\n\n免费试用期的任何未使用部分将在购买订阅时取消。\n\n注册即表示接受上述条款和条件。"; +"agreement.message" = "免费试用 7 天后,除非在试用期结束前至少提前 24 小时取消,否则此订阅将自动续订 %@。您的 Apple ID 账户将在试用期结束前 24 小时内收取续订费用。您可以在购买后前往 App Store 上的账户设置来管理和取消订阅。每个用户仅可享受一次 7 天试用优惠。免费试用期的任何未使用部分(如果提供)将在用户购买订阅时失效。所有价格均包含适用的当地营业税。\n\n注册即表示接受$1和$2。"; +"agreement.trials.yearly.plan" = "年"; +"agreement.trials.monthly.plan" = "月"; + +"agreement.message.tos" = "服务条款"; +"agreement.message.privacy" = "隐私政策"; + +"getstarted.buttons.buyaccount" = "购买账户"; + +"gdpr.collect.data.title" = "我们收集的个人信息"; +"gdpr.collect.data.description" = "用于账户管理和防止滥用的电子邮件地址。"; +"gdpr.usage.data.title" = "我们收集的个人信息的使用方式"; +"gdpr.usage.data.description" = "电子邮件地址仅用于发送订阅信息、付款确认、客户通信以及 Private Internet Access 促销优惠。"; +"gdpr.accept.button.title" = "同意并继续"; + +"update.account.email.error" = "无法修改账户电子邮件"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings new file mode 100644 index 000000000..ed78c07e6 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "壓認註冊"; +"in_progress.message" = "我們的系統正確認您的購買交易,可能需要停留在此畫面幾分鐘時間。"; +"in_progress.redeem.message" = "我們的系統正在確認您的卡 PIN 碼。這可能需要一點時間,請稍候。"; + +"success.title" = "購買完成"; +"success.message_format" = "感謝您註冊我們的服務!我們已將您的帳戶使用者名稱和密碼寄送到您的電子郵件地址:%@"; +"success.redeem.title" = "已成功兌換禮品卡"; +"success.redeem.message" = "您很快就會收到一封電子郵件,內有使用者名稱及密碼。\n\n您的登入資料"; +"success.username.caption" = "使用者名稱"; +"success.password.caption" = "密碼"; +"success.submit" = "開始使用"; + +"failure.vc_title" = "註冊失敗"; +"failure.title" = "帳戶建立失敗"; +"failure.message" = "我們目前未能建立帳戶,請稍後再試。\n\n應用程式將在重新啟動時再次嘗試建立帳戶。"; +"failure.purchase.sandbox.message" = "所選的沙盒訂閱已不再提供。"; +"failure.redeem.invalid.title" = "無效的卡 PIN 碼"; +"failure.redeem.invalid.message" = "您似乎輸入了一個無效的卡 PIN 碼,請再試一次。"; +"failure.redeem.claimed.title" = "此卡已被使用"; +"failure.redeem.claimed.message" = "這張卡似乎已經被另一個帳戶使用。您可以嘗試輸入不同的 PIN 碼。"; +"failure.submit" = "返回"; + +"unreachable.vc_title" = "錯誤"; +"unreachable.title" = "噢!"; +"unreachable.message" = "找不到網路連線。請確定您已連線上網,然後點選下方按鈕重試。\n\n您可以稍後再回來完成程序。"; +"unreachable.submit" = "重試"; + +"purchase.uncredited.alert.message" = "您有未貸記的交易,要回復帳戶資料嗎?"; +"purchase.uncredited.alert.button.cancel" = "取消"; +"purchase.uncredited.alert.button.recover" = "回復帳戶"; + +"purchase.trials.intro" = "開始 7 天免費試用"; +"purchase.trials.price.after" = "然後 %@"; +"purchase.trials.money.back" = "30 天退款保證"; +"purchase.trials.1year.protection" = "1 年隱私權和身分保護"; +"purchase.trials.anonymous" = "匿名瀏覽並隱藏 IP。"; +"purchase.trials.devices" = "同時支援 10 台裝置"; +"purchase.trials.devices.description" = "同時為最多 10 台裝置提供保護。"; +"purchase.trials.region" = "可輕鬆連線到任何地區"; +"purchase.trials.servers" = "32 個國家超過 3300 台伺服器"; +"purchase.trials.start" = "開始訂閱"; +"purchase.trials.all.plans" = "檢視所有可用方案"; + +"purchase.subscribe.now" = "馬上訂閱"; + +// WALKTHROUGH + +"walkthrough.action.next" = "下一步"; +"walkthrough.action.done" = "完成"; +"walkthrough.action.skip" = "跳過"; + +"walkthrough.page.1.title" = "同時支援 10 台裝置"; +"walkthrough.page.1.description" = "同時為多達 10 台裝置提供保護"; +"walkthrough.page.2.title" = "輕易就能連線到任何地區"; +"walkthrough.page.2.description" = "我們的伺服器遍佈全球,能為您提供全面保護。"; +"walkthrough.page.3.title" = "讓自己免受廣告滋擾"; +"walkthrough.page.3.description" = "只要啟用我們的內容阻擋器,使用 Safari 瀏覽器時就再也不會看到廣告。"; + +"share.data.buttons.accept" = "接受"; +"share.data.buttons.noThanks" = "不了,謝謝"; +"share.data.buttons.readMore" = "閱讀更多內容"; +"share.data.text.title" = "請協助我們改善服務"; +"share.data.text.description" = "為了確保服務的連線品質,您可以匿名與我們分享您的連線統計資料。這些報告不會包含任何個人識別資訊。"; +"share.data.text.footer" = "您隨時都可以在設定中控制。"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings new file mode 100644 index 000000000..7d68e2272 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "版本 %@ (%@)"; +"global.close" = "關閉"; +"global.ok" = "確認"; +"global.cancel" = "取消"; diff --git a/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings new file mode 100644 index 000000000..b4c846e04 --- /dev/null +++ b/PIA VPN dev.app/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "登入帳戶"; +"login.username.placeholder" = "使用者名稱(p1234567)"; +"login.password.placeholder" = "密碼"; +"login.submit" = "登入"; +"login.restore.button" = "收不到帳戶資料?"; +"login.error.title" = "登入"; +"login.error.validation" = "您必須輸入使用者名稱及密碼。"; +"login.error.unauthorized" = "您的使用者名稱或密碼不正確。"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "使用購買收據登入"; +"login.magic.link.title" = "使用神奇的電子郵件連結登入"; +"login.magic.link.response" = "請確認電子信箱是否已收到登入連結。"; +"login.magic.link.send" = "傳送連結"; +"login.magic.link.invalid.email" = "無效的電子郵件。請重試。"; + +"purchase.title" = "選擇 VPN 方案"; +"purchase.subtitle" = "30 天退款保證"; +"purchase.email.placeholder" = "電子郵件地址"; +"purchase.continue" = "繼續"; +"purchase.login.footer" = "已有帳號?"; +"purchase.login.button" = "登入"; +"purchase.error.title" = "購買"; +"purchase.error.validation" = "必須輸入電郵地址。"; +"purchase.error.connectivity.title" = "連線失敗"; +"purchase.error.connectivity.description" = "我們無法連線至 Private Internet Access。這可能是因為您的網路連線狀態不佳,或我們的服務在您的國家遭到封鎖。"; +"purchase.confirm.form.email" = "請輸入您的電子郵件地址"; +"purchase.confirm.plan" = "您正在購買 %@ 方案"; +"purchase.email.why" = "請提供電子郵件以便我們傳送使用者名稱及密碼。"; +"purchase.submit" = "提交"; +"purchase.or" = "或"; + +"upgrade.header" = "歡迎回來!"; +"upgrade.title" = "如果要使用 Private Internet Access,您必須續訂。"; +"upgrade.renew.now" = "立即續訂"; + + + +"redeem.title" = "兌換禮品卡"; +"redeem.subtitle" = "於下方輸入您的電子郵件地址及禮品卡或試用卡並的 %lu 位數 PIN 碼。"; +"redeem.email.placeholder" = "電子郵件地址"; +"redeem.submit" = "提交"; +"redeem.error.title" = "兌換"; +"redeem.error.code" = "代碼必須包含 %lu 個數字。"; +"redeem.error.allfields" = "請輸入您的電子郵件地址及禮品卡 PIN 碼。"; +"redeem.accessibility.back" = "返回"; +"redeem.giftcard.placeholder" = "禮品卡 PIN 碼"; + +"plan.monthly.title" = "月繳"; +"plan.yearly.title" = "年繳"; +"plan.yearly.detail_format" = "每年 %@%@"; +"plan.price_format" = "每月 %@"; +"plan.best_value" = "最佳值"; +"plan.accessibility.per_month" = "/ 月"; + +"restore.title" = "回復未貸記購買項目"; +"restore.subtitle" = "如果您透過此應用程式購買方案後收不到您的憑證,可以透過這裡要求再次傳送。此操作不會收取任何費用。"; +"restore.email.placeholder" = "電子郵件地址"; +"restore.submit" = "確定"; + +"iap.error.message.unavailable" = "Apple 伺服器目前無法使用,請稍後再試。"; +"iap.error.title" = "錯誤"; + +"agreement.trials.title" = "免費試用條款與條件"; +"agreement.trials.message" = "確認購買後,系統將從您的 Apple ID 帳號收取費用。除非您在目前訂閱期間結束前至少 24 小時取消訂閱,否則訂閱將自動續訂。在目前期間結束前 24 小時內,將從您的帳號收取續訂費用。您可在購買後,前往 App Store 的帳號設定管理和取消您的訂閱。\n\n「特定付費訂閱」可能在以您的付費方式收費前,提供免費試用。若您在我們開始以您的付費方式收費前,決定取消「付費訂閱」,請在免費試用結束前至少 24 小時取消訂閱。\n\n只有新使用者才享有免費試用的資格,且我們擁有唯一決定權。若您試圖再次註冊免費試用,我們會立即以「標準訂閱費用」向您收費。\n\n我們保留隨時解除您免費試用的權利。\n\n若您的免費試用有任何未使用的期間,將會在購買訂閱時收回。\n\n若註冊即代表您接受此條款與條件。"; +"agreement.message" = "免費試用 7 天後,除非您在試用期結束前至少 24 小時取消訂閱,否則系統將自動續訂 %@,並在試用期結束前的 24 小時內,從您的 Apple ID 帳號收取續訂費用。購買後,您可以前往 App Store 的帳號設定管理或取消您的訂閱方案。每位用戶只有一次 7 天試用的機會。若您的免費試用有任何未使用的期間,將會在購買訂閱時收回。所有價格已包括適用於當地的營業稅。\n\n若註冊,即代表您已接受 $1 與 $2。"; +"agreement.trials.yearly.plan" = "年"; +"agreement.trials.monthly.plan" = "月"; + +"agreement.message.tos" = "服務條款"; +"agreement.message.privacy" = "隱私權政策"; + +"getstarted.buttons.buyaccount" = "購買帳戶"; + +"gdpr.collect.data.title" = "我們收集的個人資料"; +"gdpr.collect.data.description" = "電子郵件地址用於管理帳戶及防止濫用。"; +"gdpr.usage.data.title" = "我們收集個人資料的用途"; +"gdpr.usage.data.description" = "電子郵件地址僅用於傳送訂閱資訊、付款確認函、客戶通訊及 Private Internet Access 的促銷優惠。"; +"gdpr.accept.button.title" = "同意並繼續"; + +"update.account.email.error" = "無法修改帳戶電子郵件"; diff --git a/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/Info.plist b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/Info.plist new file mode 100644 index 000000000..11c8b1225 Binary files /dev/null and b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/Info.plist differ diff --git a/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem new file mode 100644 index 000000000..82dec692d --- /dev/null +++ b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem @@ -0,0 +1,43 @@ +-----BEGIN CERTIFICATE----- +MIIHqzCCBZOgAwIBAgIJAJ0u+vODZJntMA0GCSqGSIb3DQEBDQUAMIHoMQswCQYD +VQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNV +BAoTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIElu +dGVybmV0IEFjY2VzczEgMB4GA1UEAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3Mx +IDAeBgNVBCkTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkB +FiBzZWN1cmVAcHJpdmF0ZWludGVybmV0YWNjZXNzLmNvbTAeFw0xNDA0MTcxNzQw +MzNaFw0zNDA0MTIxNzQwMzNaMIHoMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex +EzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNVBAoTF1ByaXZhdGUgSW50ZXJuZXQg +QWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UE +AxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBCkTF1ByaXZhdGUgSW50 +ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkBFiBzZWN1cmVAcHJpdmF0ZWludGVy +bmV0YWNjZXNzLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALVk +hjumaqBbL8aSgj6xbX1QPTfTd1qHsAZd2B97m8Vw31c/2yQgZNf5qZY0+jOIHULN +De4R9TIvyBEbvnAg/OkPw8n/+ScgYOeH876VUXzjLDBnDb8DLr/+w9oVsuDeFJ9K +V2UFM1OYX0SnkHnrYAN2QLF98ESK4NCSU01h5zkcgmQ+qKSfA9Ny0/UpsKPBFqsQ +25NvjDWFhCpeqCHKUJ4Be27CDbSl7lAkBuHMPHJs8f8xPgAbHRXZOxVCpayZ2SND +fCwsnGWpWFoMGvdMbygngCn6jA/W1VSFOlRlfLuuGe7QFfDwA0jaLCxuWt/BgZyl +p7tAzYKR8lnWmtUCPm4+BtjyVDYtDCiGBD9Z4P13RFWvJHw5aapx/5W/CuvVyI7p +Kwvc2IT+KPxCUhH1XI8ca5RN3C9NoPJJf6qpg4g0rJH3aaWkoMRrYvQ+5PXXYUzj +tRHImghRGd/ydERYoAZXuGSbPkm9Y/p2X8unLcW+F0xpJD98+ZI+tzSsI99Zs5wi +jSUGYr9/j18KHFTMQ8n+1jauc5bCCegN27dPeKXNSZ5riXFL2XX6BkY68y58UaNz +meGMiUL9BOV1iV+PMb7B7PYs7oFLjAhh0EdyvfHkrh/ZV9BEhtFa7yXp8XR0J6vz +1YV9R6DYJmLjOEbhU8N0gc3tZm4Qz39lIIG6w3FDAgMBAAGjggFUMIIBUDAdBgNV +HQ4EFgQUrsRtyWJftjpdRM0+925Y6Cl08SUwggEfBgNVHSMEggEWMIIBEoAUrsRt +yWJftjpdRM0+925Y6Cl08SWhge6kgeswgegxCzAJBgNVBAYTAlVTMQswCQYDVQQI +EwJDQTETMBEGA1UEBxMKTG9zQW5nZWxlczEgMB4GA1UEChMXUHJpdmF0ZSBJbnRl +cm5ldCBBY2Nlc3MxIDAeBgNVBAsTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAw +HgYDVQQDExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UEKRMXUHJpdmF0 +ZSBJbnRlcm5ldCBBY2Nlc3MxLzAtBgkqhkiG9w0BCQEWIHNlY3VyZUBwcml2YXRl +aW50ZXJuZXRhY2Nlc3MuY29tggkAnS7684Nkme0wDAYDVR0TBAUwAwEB/zANBgkq +hkiG9w0BAQ0FAAOCAgEAJsfhsPk3r8kLXLxY+v+vHzbr4ufNtqnL9/1Uuf8NrsCt +pXAoyZ0YqfbkWx3NHTZ7OE9ZRhdMP/RqHQE1p4N4Sa1nZKhTKasV6KhHDqSCt/dv +Em89xWm2MVA7nyzQxVlHa9AkcBaemcXEiyT19XdpiXOP4Vhs+J1R5m8zQOxZlV1G +tF9vsXmJqWZpOVPmZ8f35BCsYPvv4yMewnrtAC8PFEK/bOPeYcKN50bol22QYaZu +LfpkHfNiFTnfMh8sl/ablPyNY7DUNiP5DRcMdIwmfGQxR5WEQoHL3yPJ42LkB5zs +6jIm26DGNXfwura/mi105+ENH1CaROtRYwkiHb08U6qLXXJz80mWJkT90nr8Asj3 +5xN2cUppg74nG3YVav/38P48T56hG1NHbYF5uOCske19F6wi9maUoto/3vEr0rnX +JUp2KODmKdvBI7co245lHBABWikk8VfejQSlCtDBXn644ZMtAdoxKNfR2WTFVEwJ +iyd1Fzx0yujuiXDROLhISLQDRjVVAvawrAtLZWYK31bY7KlezPlQnl/D9Asxe85l +8jO5+0LdJ6VyOs/Hd4w52alDW/MFySDZSfQHMTIc30hLBJ8OnCEIvluVQQ2UQvoW ++no177N9L2Y+M9TcTA62ZyMXShHQGeh20rb4kK8f+iFX8NxtdHVSkxMEFSfDDyQ= +-----END CERTIFICATE----- diff --git a/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/PIA.der b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/PIA.der new file mode 100644 index 000000000..1bbbe477d Binary files /dev/null and b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/PIA.der differ diff --git a/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory new file mode 100644 index 000000000..bccd33843 Binary files /dev/null and b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory differ diff --git a/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements new file mode 100644 index 000000000..dbf9d6144 Binary files /dev/null and b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements differ diff --git a/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 new file mode 100644 index 000000000..f790851d8 Binary files /dev/null and b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 differ diff --git a/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources new file mode 100644 index 000000000..2113d6bd3 --- /dev/null +++ b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources @@ -0,0 +1,128 @@ + + + + + files + + PIA-RSA-4096.pem + + 3qHvNikZqOiKtbZEW5+oygpFyfw= + + PIA.der + + HjU73bSJKXFVdCTqzHVin0iWAak= + + + files2 + + PIA-RSA-4096.pem + + hash + + 3qHvNikZqOiKtbZEW5+oygpFyfw= + + hash2 + + Mumx0UM+qXYU8qFMbjWOP1fAVwzJ9rLugSaZumlsZqs= + + + PIA.der + + hash + + HjU73bSJKXFVdCTqzHVin0iWAak= + + hash2 + + H9JWWEVuqzBB+6d8zTmKuBJO3MG4svwdVf32sbv8nXA= + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature b/PIA VPN dev.app/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature new file mode 100644 index 000000000..e69de29bb diff --git a/PIA VPN dev.app/PkgInfo b/PIA VPN dev.app/PkgInfo new file mode 100644 index 000000000..bd04210fb --- /dev/null +++ b/PIA VPN dev.app/PkgInfo @@ -0,0 +1 @@ +APPL???? \ No newline at end of file diff --git a/PIA VPN dev.app/PlugIns/PIA VPN AdBlocker.appex/Info.plist b/PIA VPN dev.app/PlugIns/PIA VPN AdBlocker.appex/Info.plist new file mode 100644 index 000000000..3ed49e13e Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN AdBlocker.appex/Info.plist differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN AdBlocker.appex/PIA VPN AdBlocker b/PIA VPN dev.app/PlugIns/PIA VPN AdBlocker.appex/PIA VPN AdBlocker new file mode 100755 index 000000000..48ad7190e Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN AdBlocker.appex/PIA VPN AdBlocker differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN AdBlocker.appex/_CodeSignature/CodeResources b/PIA VPN dev.app/PlugIns/PIA VPN AdBlocker.appex/_CodeSignature/CodeResources new file mode 100644 index 000000000..da2dd334d --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN AdBlocker.appex/_CodeSignature/CodeResources @@ -0,0 +1,113 @@ + + + + + files + + Info.plist + + /cOwrPQkWPn7N4NBZP6TyN8EMtc= + + fallback.json + + o+Lo69t3mS7eXpQh0LOFlPTgDBY= + + + files2 + + fallback.json + + hash2 + + JOhe7KOeAE1y+F2ln85wnQGyM5BSQSJNTtWeRveUyyE= + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/PlugIns/PIA VPN AdBlocker.appex/fallback.json b/PIA VPN dev.app/PlugIns/PIA VPN AdBlocker.appex/fallback.json new file mode 100644 index 000000000..8c893ee68 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN AdBlocker.appex/fallback.json @@ -0,0 +1 @@ +[{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?101com\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?101order\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?123found\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?123freeavatars\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?180hits\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?180searchassistant\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?207\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?20a840a14a0ef7d6\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?247media\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?24log\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?24log\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?24pm-affiliation\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?2mdn\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?2o7\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?360yield\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?3lift\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?4affiliate\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?4d5\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?50websads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?518ad\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?51yes\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?600z\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?777partner\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?77tracking\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?7bpeople\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?7f1au20glg\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?7mu36somt5\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?7search\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?99count\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?a-ads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?a-counter\\.kiev.ua[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?a\\.0day.kiev.ua[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?a\\.aproductmsg.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?a\\.consumer.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?a\\.mktw.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?a\\.sakh.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?a\\.ucoz.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?a\\.ucoz.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?a\\.xanga.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?a32\\.g.a.yimg.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?aaddzz\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?abacho\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?abandonedclover\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?abc-ads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?abruptroad\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?absoluteclickscom\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?abz\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ac\\.rnm.ca[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?actionsplash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?actualdeals\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?actuallysheep\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?acuityads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?acuty1adsrv\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad-balancer\\.at[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad-balancer\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad-center\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad-miner\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad-pay\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad-rotator\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad-server\\.gulasidorna.se[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad-serverparc\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad-souk\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad-space\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad-tech\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad-up\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.100.tbn.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.71i.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.a8.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.abcnews.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.abctv.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.aboutwebservices.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.abum.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.admitad.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.afy11.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.allstar.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.altervista.org[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.amgdgt.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.anuntis.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.auditude.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.bizo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.bnmla.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.bondage.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.caradisiac.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.centrum.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.cgi.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.choiceradio.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.clix.pt[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.cooks.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.crwdcntrl.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.digitallook.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.doctissimo.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.domainfactory.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.e-kolay.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.eurosport.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.f1cd.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.flurry.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.foxnetworks.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.freecity.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.gate24.ch[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.globe7.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.grafika.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.hbv.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.hodomobile.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.httpool.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.hyena.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.iinfo.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.ilove.ch[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.infoseek.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.jamba.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.jamster.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.jetsoftware.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.keenspace.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.leadbolt.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.liveinternet.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.lupa.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.media-servers.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.mediastorm.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.mgd.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.musicmatch.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.nachtagenten.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.nozonedata.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.nttnavi.co.jp[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.nwt.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.onad.eu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.pandora.tv[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.preferances.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.profiwin.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.prv.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.rambler.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.reunion.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.sensismediasmart.com.au[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.seznam.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.simgames.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.slutload.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.smartclip.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.tbn.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.technoratimedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.thewheelof.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.turn.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.tv2.no[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.twitchguru.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.usatoday.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.virtual-nights.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.wavu.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.way.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.weatherbug.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.wsod.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.wz.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.xrea.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.yadro.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.yourmedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad\\.zanox.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad0\\.bigmir.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad01\\.mediacorpsingapore.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad1\\.emediate.dk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad1\\.emule-project.org[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad1\\.kde.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad1\\.pamedia.com.au[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad2\\.iinfo.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad2\\.linxcz.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad2\\.lupa.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad2\\.xrea.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad2flash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad3\\.iinfo.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad3\\.pamedia.com.au[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad3\\.xrea.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ad4game\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adaction\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adadvisor\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adap\\.tv[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adapt\\.tv[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adbanner\\.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adbard\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adblade\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adblockanalytics\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adboost\\.de.vu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adboost\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adbooth\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adbot\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adbrite\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adbrn\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adbroker\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adbunker\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adbutler\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adbuyer\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adbuyer3\\.lycos.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adcash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adcast\\.deviantart.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adcell\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adcenter\\.mdf.se[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adcenter\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adcentriconline\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adcept\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adclient\\.uimserv.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adclient1\\.tucows.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adcomplete\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adconion\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adcontent\\.gamespy.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adcycle\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?add\\.newmedia.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?addfreestats\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?addme\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adecn\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ademails\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adengage\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adexchangegate\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adexchangeprediction\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adexcite\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adexpose\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adext\\.inkclub.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adf\\.ly[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adfarm\\.mediaplex.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adflight\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adforce\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adform\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adform\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adformdsp\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adgardener\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adgoto\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adgridwork\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adhese\\.be[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adhese\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adimage\\.guardian.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adimages\\.been.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adimages\\.carsoup.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adimages\\.go.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adimages\\.homestore.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adimages\\.omroepzeeland.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adimages\\.sanomawsoy.fi[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adimg\\.cnet.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adimg\\.com.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adimg\\.uimserv.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adimg1\\.chosun.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adimgs\\.sapo.pt[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adimpact\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adincube\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adinjector\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adinterax\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adisfy\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adition\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adition\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adition\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adizio\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adjix\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adjug\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adjuggler\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adjuggler\\.yourdictionary.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adjustnetwork\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adk2\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adk2ads\\.tictacti.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adland\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adledge\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adlegend\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adlog\\.com.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adloox\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adlooxtracking\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adlure\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adm\\.fwmrm.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admagnet\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admailtiser\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adman\\.gr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adman\\.in.gr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adman\\.otenet.gr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admanagement\\.ch[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admanager\\.btopenworld.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admanager\\.carsoup.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admantx\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admarketplace\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admarvel\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admax\\.nexage.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admedia\\.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admeld\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admerize\\.be[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admeta\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admex\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adminder\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adminshop\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admized\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admob\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admonitor\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?admotion\\.com.ar[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adnet-media\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adnet\\.asahi.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adnet\\.biz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adnet\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adnet\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adnet\\.worldreviewer.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adnetinteractive\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adnetwork\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adnetworkperformance\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adnews\\.maddog2000.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adnotch\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adnxs\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adocean\\.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adonspot\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adoperator\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adorigin\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adotmob\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adpenguin\\.biz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adpepper\\.dk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adpepper\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adperium\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adpia\\.vn[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adplus\\.co.id[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adplxmd\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adprofile\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adprojekt\\.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adq\\.nextag.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adrazzi\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adreactor\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adreclaim\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adrecreate\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adremedy\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adreporting\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adres\\.internet.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adrevolver\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adriver\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adrolays\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adrotate\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adrotator\\.se[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adrotic\\.girlonthenet.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adrta\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads-click\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.4tube.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.5ci.lt[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.abovetopsecret.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.aceweb.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.activestate.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.adfox.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.administrator.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.adshareware.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.adultfriendfinder.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.adultswim.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.advance.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.adverline.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.affiliates.match.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.ak.facebook.com.edgesuite.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.allvatar.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.alt.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.amdmb.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.amigos.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.aol.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.aol.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.apn.co.nz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.appsgeyser.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.as4x.tmcs.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.as4x.tmcs.ticketmaster.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.asia1.com.sg[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.asiafriendfinder.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.ask.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.aspalliance.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.avazu.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.batpmturner.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.belointeractive.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.berlinonline.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.betanews.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.betfair.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.betfair.com.au[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.bigchurch.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.bigfoot.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.bing.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.bittorrent.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.blog.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.bloomberg.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.bluelithium.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.bluemountain.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.bluesq.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.bonniercorp.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.boylesports.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.brabys.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.brazzers.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.bumq.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.businessweek.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.canalblog.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.canoe.ca[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.casinocity.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.cbc.ca[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.cc[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.cc-dt.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.centraliprom.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.cgnetworks.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.channel4.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.clearchannel.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.co.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.com.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.contactmusic.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.contentabc.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.contextweb.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.crakmedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.creative-serving.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.creativematch.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.cricbuzz.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.cybersales.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.dada.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.datinggold.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.datingyes.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.dazoot.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.deltha.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.dennisnet.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.desmoinesregister.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.detelefoongids.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.deviantart.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.digital-digest.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.digitalmedianet.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.digitalpoint.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.directionsmag.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.domain.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.domeus.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.eagletribune.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.easy-forex.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.eatinparis.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.economist.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.edbindex.dk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.egrana.com.br[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.electrocelt.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.elitetrader.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.emirates.net.ae[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.epltalk.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.eu.msn.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.exactdrive.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.expat-blog.biz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.expedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.factorymedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.fairfax.com.au[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.faxo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.ferianc.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.filmup.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.financialcontent.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.flooble.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.fool.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.footymad.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.forbes.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.forbes.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.forium.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.fortunecity.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.fotosidan.se[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.foxnetworks.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.foxnews.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.freecity.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.friendfinder.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.ft.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.gamecity.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.gamershell.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.gamespyid.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.gamigo.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.gaming-universe.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.gawker.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.geekswithblogs.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.glispa.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.gmodules.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.goyk.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.gplusmedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.gradfinder.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.grindinggears.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.groundspeak.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.gsm-exchange.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.gsmexchange.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.guardian.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.guardianunlimited.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.guru3d.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.hardwaresecrets.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.harpers.org[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.hbv.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.hearstmags.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.heartlight.org[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.heias.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.hideyourarms.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.hollywood.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.horsehero.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.horyzon-media.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.iafrica.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.ibest.com.br[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.ibryte.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.icq.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.ign.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.img.co.za[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.imgur.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.indiatimes.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.infi.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.internic.co.il[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.ipowerweb.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.isoftmarketing.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.itv.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.iwon.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.jewishfriendfinder.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.jiwire.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.jobsite.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.jpost.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.jubii.dk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.justhungry.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.kaktuz.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.kelbymediagroup.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.kinobox.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.kinxxx.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.kompass.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.krawall.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.lesbianpersonals.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.linkedin.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.linuxfoundation.org[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.linuxjournal.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.linuxsecurity.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.livenation.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.mariuana.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.massinfra.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.mcafee.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.mediaodyssey.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.medienhaus.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.mgnetwork.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.mmania.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.moceanads.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.motor-forum.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.motormedia.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.msn.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.multimania.lycos.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.nationalgeographic.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.ncm.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.netmechanic.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.networksolutions.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.newdream.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.newgrounds.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.newmedia.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.newsint.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.newsquest.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.ninemsn.com.au[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.nj.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.nola.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.nordichardware.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.nordichardware.se[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.nwsource.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.nyi.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.nytimes.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.nyx.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.nzcity.co.nz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.o2.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.oddschecker.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.okcimg.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.ole.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.olivebrandresponse.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.oneplace.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.optusnet.com.au[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.outpersonals.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.passion.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.pennet.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.penny-arcade.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.phpclasses.org[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.planet.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.pni.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.pof.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.powweb.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.primissima.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.printscr.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.prisacom.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.program3.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.psd2html.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.pushplay.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.quoka.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.rcs.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.recoletos.es[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.rediff.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.redlightcenter.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.redtube.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.resoom.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.returnpath.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.s3.sitepoint.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.satyamonline.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.savannahnow.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.saymedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.scifi.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.seniorfriendfinder.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.servebom.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.sexinyourcity.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.shizmoo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.shopstyle.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.sift.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.silverdisc.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.slim.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.smartclick.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.soft32.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.space.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.sptimes.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.stackoverflow.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.sun.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.supplyframe.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.t-online.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.tahono.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.techtv.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.telegraph.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.themovienation.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.thestar.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.tmcs.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.totallyfreestuff.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.townhall.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.trinitymirror.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.tripod.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.tripod.lycos.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.tripod.lycos.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.tripod.lycos.es[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.tripod.lycos.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.tripod.lycos.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.tripod.spray.se[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.tso.dennisnet.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.twitter.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.uknetguide.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.ultimate-guitar.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.uncrate.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.undertone.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.usatoday.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.v3.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.verticalresponse.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.vgchartz.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.videosz.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.virtual-nights.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.virtualcountries.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.vnumedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.waps.cn[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.wapx.cn[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.weather.ca[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.web.aol.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.web.cs.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.web.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.webmasterpoint.org[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.websiteservices.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.whi.co.nz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.whoishostingthis.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.wiezoekje.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.wikia.nocookie.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.wineenthusiast.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.wwe.biz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.xhamster.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.xtra.co.nz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.y-0.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.yahoo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.yap.yahoo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.yimg.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.yldmgrimg.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.yourfreedvds.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.youtube.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.zdnet.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads\\.ztod.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads03\\.redtube.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads1\\.canoe.ca[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads1\\.mediacapital.pt[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads1\\.msn.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads1\\.rne.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads1\\.virtual-nights.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads10\\.speedbit.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads180\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads2\\.brazzers.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads2\\.clearchannel.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads2\\.contentabc.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads2\\.gamecity.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads2\\.jubii.dk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads2\\.net-communities.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads2\\.oneplace.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads2\\.rne.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads2\\.virtual-nights.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads2\\.xnet.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads2004\\.treiberupdate.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads3\\.contentabc.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads3\\.gamecity.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads3\\.virtual-nights.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads4\\.clearchannel.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads4\\.gamecity.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads4\\.virtual-nights.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads4homes\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads5\\.canoe.ca[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads5\\.virtual-nights.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads6\\.gamecity.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads7\\.gamecity.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ads8\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsafeprotected\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsatt\\.abc.starwave.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?Adsatt\\.ABCNews.starwave.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsatt\\.espn.go.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsatt\\.espn.starwave.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?Adsatt\\.go.starwave.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsby\\.bidtheatre.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adscale\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adscholar\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adscience\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adscpm\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsdaq\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsdk\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsend\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsensecustomsearchads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserv\\.evo-x.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserv\\.gamezone.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserv\\.iafrica.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserve\\.ams.rhythmxchange.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.43plc.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.71i.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.adultfriendfinder.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.aidameter.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.aol.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.betandwin.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.bing.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.bizhat.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.break-even.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.cams.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.digitoday.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.finditquick.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.flossiemediagroup.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.freecity.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.friendfinder.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.hardsextube.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.hardwareanalysis.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.html.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.hwupgrade.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.irishwebmasterforum.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.janes.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.libero.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.news.com.au[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.ngz-network.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.nydailynews.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.o2.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.oddschecker.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.omroepzeeland.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.portalofevil.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.portugalmail.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.portugalmail.pt[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.pressboard.ca[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.sanomawsoy.fi[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.sciflicks.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.sharewareonline.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.spankaway.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.theonering.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.twitpic.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.viagogo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.virginmedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver\\.yahoo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver01\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver1-images\\.backbeatmedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver1\\.backbeatmedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver1\\.mindshare.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver1\\.ogilvy-interactive.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserver2\\.mindshare.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserverplus\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserversolutions\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adserving\\.unibet.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adservinginternational\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsfac\\.eu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsfac\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsfac\\.us[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adside\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsk2\\.co[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adskape\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsklick\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsmarket\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsmart\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsmart\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsmogo\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsnative\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsoftware\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsoldier\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsonar\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adspace\\.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adspeed\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adspirit\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsponse\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsremote\\.scrippsnetworks.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsrevenue\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsrv\\.deviantart.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsrv\\.eacdn.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsrv\\.iol.co.za[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsrvr\\.org[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsstat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adstage\\.io[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adstat\\.4u.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adstest\\.weather.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsupply\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adswizz\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsymptotic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsynergy\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsys\\.townnews.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adsystem\\.simplemachines.org[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adtech\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adtechjp\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adtechus\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adtegrity\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adthis\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adtiger\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adtoll\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adtology\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adtoma\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adtrace\\.org[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adtrade\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adtrading\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adtrak\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adtriplex\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adultadvertising\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adv-adserver\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adv-banner\\.libero.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adv\\.cooperhosting.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adv\\.freeonline.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adv\\.hwupgrade.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adv\\.livedoor.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adv\\.nexthardware.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adv\\.webmd.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adv\\.wp.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adv\\.yo.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advariant\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adventory\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advert\\.bayarea.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advert\\.dyna.ultraweb.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adverticum\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adverticum\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adverticus\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertise\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertiseireland\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertiserurl\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertisespace\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertising\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertising\\.guildlaunch.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertisingbanners\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertisingbox\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertisingtag\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertmarket\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertmedia\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertpro\\.sitepoint.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertpro\\.ya.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adverts\\.carltononline.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertserve\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertstream\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advertwizard\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advfromnwl\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advideo\\.uimserv.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adview\\.ppro.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advisormedia\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adviva\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?advnt\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adwareremovergold\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adwhirl\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adwitserver\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adworldnetwork\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adworx\\.at[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adworx\\.be[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adworx\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adx\\.allstar.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adx\\.atnext.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adxpansion\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adxpose\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adxprts\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adxvalue\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adyea\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adz2you\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adzbazar\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adzerk\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adzerk\\.s3.amazonaws.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?adzones\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?af-ad\\.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affbuzzads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affili\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliate\\.1800flowers.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliate\\.doubleyourdating.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliate\\.dtiserv.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliate\\.gamestop.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliate\\.mercola.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliate\\.mogs.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliate\\.offgamers.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliate\\.travelnow.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliate\\.treated.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliate\\.viator.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliatefuel\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliatefuture\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliates\\.allposters.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliates\\.babylon.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliates\\.digitalriver.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliates\\.globat.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliates\\.internationaljock.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliates\\.streamray.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliates\\.thinkhost.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliates\\.thrixxx.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliates\\.ultrahosting.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliatetracking\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliatetracking\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliatewindow\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?affiliation-france\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?afftracking\\.justanswer.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?agreemand\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ah-ha\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ahalogy\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?aidu-ads\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?aim4media\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?aistat\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?aktrack\\.pubmatic.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?alclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?alenty\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?alexa-sitestats\\.s3.amazonaws.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?alipromo\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?all4spy\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?alladvantage\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?allosponsor\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?alphonso\\.tv[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?amazingcounters\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?amazon-adsystem\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ambitiousagreement\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?americash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?amung\\.us[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?an\\.tacoda.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?anahtars\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?analytics\\.adpost.org[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?analytics\\.google.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?analytics\\.live.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?analytics\\.yahoo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?anm\\.intelli-direct.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?annonser\\.dagbladet.no[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?anxiousapples\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?apester\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?api\\.intensifier.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?app\\.adblockhyper.us[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?appsflyer\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?apture\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?apusx\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?arc1\\.msn.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?arcadebanners\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ard\\.xxxblackbook.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?are-ter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?as\\.webmd.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?as1\\.advfn.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?assets1\\.exgfnetwork.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?assoc-amazon\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?at-adserver\\.alltop.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?atdmt\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?athena-ads\\.wikia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?attributiontracker\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?atwola\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?auctionads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?auctionads\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?audience2media\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?audienceinsights\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?audit\\.median.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?audit\\.webinform.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?augur\\.io[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?auto-bannertausch\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?autohits\\.dk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?avenuea\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?avocet\\.io[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?avpa\\.javalobby.org[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?avsads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?avzadsrv\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?awempire\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?awin1\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?b-1st\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?b\\.aol.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?b\\.engadget.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?b0b1o\\.bid[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?b59812ee54afcabd\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ba\\.afl.rakuten.co.jp[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?babs\\.tv2.dk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?backbeatmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banik\\.redigy.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner-exchange-24\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.ad.nu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.ambercoastcasino.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.blogranking.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.buempliz-online.ch[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.casino.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.casinodelrio.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.cotedazurpalace.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.coza.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.easyspace.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.elisa.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.eurogrand.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.getgo.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.goldenpalace.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.img.co.za[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.inyourpocket.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.kiev.ua[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.linux.se[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.media-system.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.mindshare.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.nixnet.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.noblepoker.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.northsky.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.orb.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.penguin.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.rbc.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.relcom.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.tanto.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.titan-dsl.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.vadian.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.webmersion.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banner\\.wirenode.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannerads\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannerboxes\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannercommunity\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannerconnect\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannerconnect\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannerexchange\\.cjb.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannerflow\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannergrabber\\.internet.gr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannerhost\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannerimage\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannerlandia\\.com.ar[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannermall\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannermarkt\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannerpower\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.adultfriendfinder.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.amigos.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.asiafriendfinder.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.audioholics.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.babylon-x.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.bol.com.br[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.cams.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.clubseventeen.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.czi.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.dine.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.direction-x.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.directnic.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.easydns.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.freett.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.friendfinder.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.getiton.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.iq.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.isoftmarketing.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.linkbuddies.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.passion.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.resultonline.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.sexsearch.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.sys-con.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.thomsonlocal.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.videosz.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.virtuagirlhd.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?banners\\.wunderground.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannerserver\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannersgomlm\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannershotlink\\.perfectgonzo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannersng\\.yell.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannerspace\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannerswap\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannertesting\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannery\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bannieres\\.acces-contenu.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bans\\.adserver.co.il[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bans\\.bride.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?barnesandnoble\\.bfast.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?basebanner\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?baskettexture\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bat\\.bing.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bawdybeast\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?baypops\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bbelements\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bbn\\.img.com.ua[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?beamincrease\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?begun\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?behavioralengine\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?belstat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?belstat\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?berp\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?best-pr\\.info[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?best-top\\.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bestsearch\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bidclix\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bidclix\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bidr\\.io[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bidswitch\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bidtrk\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bidvertiser\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bigbangmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bigclicks\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?billboard\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bitads\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bitmedianetwork\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bizad\\.nikkeibp.co.jp[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bizographics\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bizrate\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?blast4traffic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?blingbucks\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?blogads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?blogcounter\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?blogherads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?blogrush\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?blogtoplist\\.se[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?blogtopsites\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?blueadvertise\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bluekai\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bluelithium\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bluewhaleweb\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bm\\.annonce.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bn\\.bfast.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?boersego-ads\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?boilingbeetle\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?boldchat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?boom\\.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?boomads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?boost-my-pr\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?boudja\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bounceexchange\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?box\\.anchorfree.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bpath\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?braincash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?brandreachsys\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?brassrule\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bridgetrack\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?brightinfo\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?british-banners\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?broadboundary\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bs\\.yandex.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bttrack\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?budsinc\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bullseye\\.backbeatmedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?buyhitscheap\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?buysellads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?buzzonclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?bwp\\.download.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?c\\.bigmir.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?c1\\.nowlinux.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?c1exchange\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?calmfoot\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?campaign\\.bharatmatrimony.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?caniamedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?capacitly\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?carambo\\.la[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?carbonads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?carbonads\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?casalemedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?casalmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cash4members\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cash4popup\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cashcrate\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cashengines\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cashfiesta\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cashlayer\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cashpartner\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?casinogames\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?casinopays\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?casinorewards\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?casinotraffic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?casinotreasure\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?casterist\\.info[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cbanners\\.virtuagirlhd.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cbmall\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cdn\\.freefarcy.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cdn\\.segment.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cecash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?centerpointmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ceskydomov\\.alias.ngs.modry.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cetrk\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cgicounter\\.puretec.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ch\\.questionmarket.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?chameleon\\.ad[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?channel1vids\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?channelintelligence\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?chart\\.dk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?chartbeat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?chartbeat\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?checkm8\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?checkstat\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cherrythread\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?chestionar\\.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?chiefcurrent\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?chitika\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?christingel\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cinstein\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cityads\\.telus.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cj\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cjbmanagement\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cjlog\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?claria\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?class-act-clicks\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?click\\.absoluteagency.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?click\\.fool.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?click\\.kmindex.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?click2freemoney\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?click2paid\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickability\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickadz\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickagents\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickbank\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickbank\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickbooth\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickboothlnk\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickbrokers\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickcompare\\.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickdensity\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickedyclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickhereforcellphones\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickhouse\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickhype\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clicklink\\.jp[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickmedia\\.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickonometrics\\.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clicks\\.equantum.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clicks\\.mods.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickserve\\.cc-dt.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clicksor\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clicktag\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickthruserver\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickthrutraffic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clicktrace\\.info[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clicktrack\\.ziyu.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clicktracks\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clicktrade\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickxchange\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clickz\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clicmanager\\.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clientmetrics-pa\\.googleapis.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clients\\.tbo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clikerz\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cliksolution\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clixgalore\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clk\\.konflab.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clkads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clkrev\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cloudcoins\\.biz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clrstm\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cluster\\.adultworld.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?clustrmaps\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cnomy\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cnt\\.spbland.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cnt1\\.pocitadlo.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?code-server\\.biz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?coin-hive\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?coinhive\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cointraffic\\.io[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?colonize\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?comclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?commindo-media-ressourcen\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?commissionmonster\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?compactbanner\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?comprabanner\\.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?concernrain\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?confirmed-profits\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?connatix\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?connextra\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?consciouscabbage\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?contaxe\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?content\\.acc-hd.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?content\\.ad[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?contextweb\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?conversantmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?conversionruler\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cookies\\.cmpnet.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?copperchickens\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?copycarpenter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?copyrightaccesscontrols\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?coremetrics\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cottawa\\.info[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?count\\.rbc.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?count\\.rin.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?count\\.west263.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counted\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counter\\.bloke.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counter\\.cnw.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counter\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counter\\.dreamhost.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counter\\.fateback.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counter\\.mirohost.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counter\\.mojgorod.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counter\\.nowlinux.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counter\\.rambler.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counter\\.search.bg[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counter\\.snackly.co[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counter\\.sparklit.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counter\\.yadro.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counters\\.honesty.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counting\\.kmindex.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?counts\\.tucows.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?coupling-media\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cowledges\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cp\\.abbp1.pw[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cpalead\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cpays\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cpmaffiliation\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cpmstar\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cpx\\.to[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cpxinteractive\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cqcounter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?crakmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?craktraffic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?crawlability\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?crawlclocks\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?crazypopups\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?creafi-online-media\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?creative\\.whi.co.nz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?creatives\\.as4x.tmcs.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?creatives\\.livejasmin.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?credishe\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?crispads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?criteo\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?critictruck\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?croissed\\.info[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?crowdgravity\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?crtv\\.mate1.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?crwdcntrl\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ctnet2\\.in[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ctnetwork\\.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cubics\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?curtaincows\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?customad\\.cnn.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cutecushion\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cxense\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cyberbounty\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?cybermonitor\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?d\\.adroll.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?d2cmedia\\.ca[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dakic-ia-300\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?danban\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dapper\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?datashreddergold\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dbbsrv\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dc-storm\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?de17a\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dealdotcom\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?debtbusterloans\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?decisiveducks\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?decknetwork\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?deloo\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?deloton\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?demandbase\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?demdex\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?deployads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?di1\\.shopping.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dialerporn\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dianomi\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?didtheyreadit\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?digital-ads\\.s3.amazonaws.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?digitalmerkat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?direct-xxx-access\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?directaclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?directivepub\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?directleads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?directorym\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?directtrack\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?discountclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?displayadsmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?disqusads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dist\\.belnk.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dk4ywix\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dmtracker\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dmtracking\\.alibaba.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dmtracking2\\.alibaba.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dnads\\.directnic.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?docksalmon\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?domaining\\.in[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?domainsponsor\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?domainsteam\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?domdex\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?doubleclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?doubleclick\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?doubleclick\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?doublepimp\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?doubtfulrainstorm\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dragzebra\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?drumcash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dynamic\\.fmpub.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?dyntrk\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?e-adimages\\.scrippsnetworks.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?e-bannerx\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?e-debtconsolidation\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?e-m\\.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?e-n-t-e-r-n-e-x\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?e-planning\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?e\\.kde.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eadexchange\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eas\\.almamedia.fi[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?easyhits4u\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ebayadvertising\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ebocornac\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ebuzzing\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ecircle-ag\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eclick\\.vn[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ecoupons\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?edgeio\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?effectivemeasure\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?effectivemeasure\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eiv\\.baidu.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?elasticchange\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?elephantqueue\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?elitedollars\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?elitetoplist\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?elthamely\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?emarketer\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?emediate\\.dk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?emediate\\.eu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?engine\\.espace.netavenir.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?enginenetwork\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?enlarget\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?enoratraffic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?enquisite\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ensighten\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?entercasino\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?entrecard\\.s3.amazonaws.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eqads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ero-advertising\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?estat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?etahub\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?etargetnet\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?etracker\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eu-adcenter\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eu1\\.madsone.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eur\\.a1.yimg.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eurekster\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?euroclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?euros4click\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eusta\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?evergage\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?evidencecleanergold\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ewebcounter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?exchange-it\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?exchange\\.bg[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?exchangead\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?exchangeclicksonline\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?exclusivebrass\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?exelator\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?exit76\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?exitexchange\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?exitfuel\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?exoclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?exogripper\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?experteerads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?exponential\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?express-submit\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?extractorandburner\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?extreme-dm\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?extremetracking\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eyeblaster\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eyeota\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eyereturn\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eyeviewads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?eyewonder\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ezula\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?f5biz\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fast-adv\\.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fastclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fastclick\\.com.edgesuite.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fastclick\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fc\\.webmasterpro.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?feedbackresearch\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?feedjit\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ffxcam\\.fairfax.com.au[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fimserve\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?findcommerce\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?findepended\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?findyourcasino\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fineclicks\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?first\\.nova.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?firstlightera\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?flashtalking\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?flavordecision\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fleshlightcash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?flexbanner\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?floodprincipal\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?flowgo\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?flurry\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fonecta\\.leiki.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?foo\\.cosmocode.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?forex-affiliate\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fpctraffic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fpctraffic2\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fqtag\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fragmentserv\\.iac-online.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?free-banners\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?freebanner\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?freelogs\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?freeonlineusers\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?freepay\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?freeskreen\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?freestats\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?freestats\\.tv[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?freewebcounter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fullstory\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?functionalclam\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?funklicks\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?funpageexchange\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fusionads\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fusionquest\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?futuristicfairies\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fuzzyflavor\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?fxstyle\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?g3j2wzmon8b\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ga87z2o\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?galaxien\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?game-advertising-online\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?gamehouse\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?gamesites100\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?gamesites200\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?gamesitestop100\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?gator\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?gbanners\\.hornymatches.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?geo\\.digitalpoint.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?geobanner\\.adultfriendfinder.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?geovisite\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?getclicky\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?giddycoat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?globalismedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?globaltakeoff\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?globe7\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?globus-inter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?gmads\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?go-clicks\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?go-rank\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?goingplatinum\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?goldstats\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?google-analytics\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?googleadservices\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?googlesyndication\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?gorgeousground\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?gostats\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?gp\\.dejanews.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?gpr\\.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?grafstat\\.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?grapeshot\\.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?graph\\.instagram.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?greetzebra\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?greystripe\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?gtop100\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?guardedgovernor\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?guitarbelieve\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?gunggo\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?harrenmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?harrenmedianetwork\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?havamedia\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?heias\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hellobar\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hentaicounter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?herbalaffiliateprogram\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hexusads\\.fluent.ltd.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?heyos\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hgads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hidden\\.gogoceleb.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hightrafficads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hilariouszinc\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?histats\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hit-parade\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hit\\.bg[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hit\\.ua[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hit\\.webcentre.lycos.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hitbox\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hitcents\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hitfarm\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hitiz\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hitlist\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hitlounge\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hitometer\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hits\\.europuls.eu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hits\\.informer.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hits\\.puls.lv[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hits\\.theguardian.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hits4me\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hits4pay\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hitslink\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hittail\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hollandbusinessadvertising\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?homepageking\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hostedads\\.realitykings.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hotjar\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hotkeys\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hotlog\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hotrank\\.com.tw[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hs-analytics\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?htmlhubing\\.xyz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?httpool\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hurricanedigitalmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hydramedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hyperbanner\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?hypertracker\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?i-clicks\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?i\\.xx.openx.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?i1img\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?i1media\\.no[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ia\\.iinfo.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?iad\\.anm.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?iadnet\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?iasds01\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?iconadserver\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?icptrack\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?idcounter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?identads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?idtargeting\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ientrymail\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?iesnare\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ifa\\.tube8live.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ilbanner\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ilead\\.itrack.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?illustriousoatmeal\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?imageads\\.canoe.ca[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?imagecash\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?images-pw\\.secureserver.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?images\\.v3.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?imarketservices\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?img\\.prohardver.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?imgpromo\\.easyrencontre.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?imonitor\\.nethost.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?imprese\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?impressionmedia\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?impressionz\\.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?imrworldwide\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?inboxdollars\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?incentaclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?incognitosearches\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?incrediblesugar\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?indexstats\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?indexww\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?indieclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?industrybrains\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?inetlog\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?infinite-ads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?infinityads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?infolinks\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?information\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?inmobi\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?innovid\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?inringtone\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?insightexpress\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?insightexpressai\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?inspectorclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?instantmadness\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?instinctiveads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?intelliads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?intellitxt\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?interactive\\.forthnet.gr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?intergi\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?internetfuel\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?interreklame\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?interstat\\.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ioam\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ip\\.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ip193\\.cn[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?iperceptions\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ipro\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ireklama\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?itfarm\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?itop\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?its-that-easy\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?itsptp\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ivwbox\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ivykiosk\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?jcount\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?jinkads\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?joetec\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?joneself\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?js\\.users.51.la[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?jsecoin\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?juicyads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?jumptap\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?justrelevant\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?justwebads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?k\\.iinfo.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?kanoodle\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?kargo\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?karonty\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?keymedia\\.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?kindads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?kissmetrics\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?kliks\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?kniverto\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?knorex\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?koinser\\.in[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?komoona\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?kompasads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?kontera\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ktu\\.sv2.biz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lacerta\\.space[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lakequincy\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?launchbit\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?layer-ad\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?layer-ads\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lbn\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lead-analytics\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?leadboltads\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?leadclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?leadingedgecash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?leadzupc\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?levelrate\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lfstmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?liftdna\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ligatus\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ligatus\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lightningcast\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lightspeedcash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lijit\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?limpingline\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?link-booster\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?link4ads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?linkadd\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?linkbuddies\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?linkexchange\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?linkprice\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?linkrain\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?linkreferral\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?links-ranking\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?linkshighway\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?linkstorms\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?linkswaper\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?linktarget\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?liquidad\\.narrowcastmedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?liveadexchanger\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?liveintent\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?liverail\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lizardslaugh\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?loading321\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?log\\.btopenworld.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?logger\\.snackly.co[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?logua\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lop\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lopsidedspoon\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?loudloss\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lp3tdqle\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lucidmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lucklayed\\.info[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lumpyleaf\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?lzjl\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?m\\.trb.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?m1\\.webstats4u.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?m32\\.media[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?m4n\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mackeeperapp\\.mackeeper.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?madclient\\.uimserv.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?madisonavenue\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mads\\.cnet.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?madvertise\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?marchex\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?market-buster\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?marketing\\.888.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?marketing\\.hearstmagazines.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?marketing\\.nyi.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?marketing\\.osijek031.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?marketingsolutions\\.yahoo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mas\\.sector.sk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mastermind\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?matchcows\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?matchcraft\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?matheranalytics\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mathtag\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?max\\.i12.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?maximumcash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mbs\\.megaroticlive.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mbuyu\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mdotm\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?measuremap\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?media-adrunner\\.mycomputer.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?media-servers\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?media\\.ftv-publicite.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?media\\.funpic.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?media\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?media6degrees\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediaarea\\.eu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediabridge\\.cc[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediadvertising\\.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediageneral\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediaiqdigital\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediamath\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediamgr\\.ugo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediaplazza\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediaplex\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediascale\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediaserver\\.bwinpartypartners.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediatext\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediatrking\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediavine\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediavoice\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediax\\.angloinfo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mediaz\\.angloinfo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?medleyads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?medyanetads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?megacash\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?megastats\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?megawerbung\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mellowads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?metaffiliation\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?metanetwork\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?methodcash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?metrics\\.cnn.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?metrics\\.ctv.ca[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?metrics\\.foxnews.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?metrics\\.govexec.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?metrics\\.windowsitpro.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?metrilo\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mgid\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?miarroba\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?microstatic\\.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?microticker\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?midnightclicking\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?misstrends\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mixedreading\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mixpanel\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mixtraffic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mjxads\\.internet.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ml314\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mlm\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mmismm\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mmtro\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?moatads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mob\\.system-onlline.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mobclix\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mobileiconnect\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mocean\\.mobi[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?moggattice\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?monetate\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?moneyexpert\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?monsterpops\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mopub\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mouseflow\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mowfruit\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mpstat\\.us[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mr-rank\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mrskincash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mstrlytcs\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mtrcs\\.samba.tv[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mtree\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?musiccounter\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?muwmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?myaffiliateprogram\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mybloglog\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mybuys\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mycounter\\.ua[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mymoneymakingapp\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mypagerank\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mypagerank\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mypowermall\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mystat-in\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mystat\\.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mytop-in\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mytrafficads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?mzbcdn\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?n69\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?naj\\.sk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?namimedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?nastydollars\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?nativeroll\\.tv[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?navigator\\.io[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?navrcholu\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?nbjmp\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ncaudienceexchange\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ndparking\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?nedstat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?nedstat\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?nedstatbasic\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?nedstatpro\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?nend\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?neocounter\\.neoworx-blog-tools.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?neoffic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?nephritish\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?net-filter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?netaffiliation\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?netagent\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?netclickstats\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?netcommunities\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?netdirect\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?netincap\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?netpool\\.netbookia.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?netshelter\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?neudesicmediagroup\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?newads\\.bangbros.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?newbie\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?newnet\\.qsrch.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?newnudecash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?newopenx\\.detik.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?newstarads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?newt1\\.adultadworld.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?newt1\\.adultworld.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?newtopsites\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?nexage\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ng3\\.ads.warnerbros.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?nitroclicks\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?novem\\.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ns1p\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ntv\\.io[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?nuggad\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?numax\\.nu-1.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?nuseek\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?nzaza\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oas\\.benchmark.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oas\\.foxnews.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oas\\.repubblica.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oas\\.roanoke.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oas\\.salon.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oas\\.toronto.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oas\\.uniontrib.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oas\\.villagevoice.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oascentral\\.businessweek.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oascentral\\.chicagobusiness.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oascentral\\.fortunecity.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oascentral\\.register.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oclasrv\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oewa\\.at[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oewabox\\.at[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?offerforge\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?offermatica\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?olivebrandresponse\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?omniture\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?onclasrv\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?onclickads\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oneandonlynetwork\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?onenetworkdirect\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?onestat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?onestatfree\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?online-metrix\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?onlinecash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?onlinecashmethod\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?onlinerewardcenter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?open\\.oneplus.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?openad\\.tf1.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?openad\\.travelnow.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?openads\\.friendfinder.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?openads\\.org[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?openx\\.angelsgroup.org.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?openx\\.blindferret.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?opienetwork\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?opinionstage\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?optimize-stats\\.voxmedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?optimost\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?optmd\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ordingly\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ota\\.cartrawler.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?otto-images\\.developershed.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?outbrain\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?overture\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?owebmoney\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?owneriq\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oxado\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oxcash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?oxen\\.hillcountrytexas.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pagead\\.l.google.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pagefair\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pagefair\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pagerank-ranking\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pagerank-submitter\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pagerank-united\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pagerank4you\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pageranktop\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?parsely\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?partner-ads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?partner\\.pelikan.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?partnerad\\.l.google.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?partnercash\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?partners\\.priceline.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?passion-4\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pay-ads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?paycounter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?paypopup\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?payserve\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pbnet\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pbterra\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pcash\\.imlive.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?peacepowder\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?peep-auktion\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?peer39\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pennyweb\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pepperjamnetwork\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?percentmobile\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?perfectaudience\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?perfiliate\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?performancerevenue\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?performancerevenues\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?performancing\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?permutive\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?personagraph\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pgmediaserve\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pgpartner\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pheedo\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?phoenix-adrunner\\.mycomputer.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?photographpan\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?phpadsnew\\.new.natuurpark.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?phpmyvisites\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?picadmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?piet2eix3l\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pietexture\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pillscash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pimproll\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pixel\\.adsafeprotected.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pixel\\.condenastdigital.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pixel\\.digitru.st[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pixel\\.jumptap.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pixel\\.redditmedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?play4traffic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?playhaven\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?playmobileads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?plista\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?plugrush\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pointroll\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pop-under\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?popads\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?popflawlessads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?popub\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?popunder\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?popup\\.msn.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?popupmoney\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?popupnation\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?popups\\.infostart.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?popuptraffic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?porngraph\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?porntrack\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?possibleboats\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?postrelease\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?potenza\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pr-star\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?practicetoothpaste\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?praddpro\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?prchecker\\.info[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?precisioncounter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?predictad\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?premium-offers\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?presetrabbits\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?primaryads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?primetime\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?privatecash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?privy\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?prmtracking\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pro-advertising\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?proext\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?profero\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?profitrumour\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?projectwonderful\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?promo\\.badoink.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?promo\\.ulust.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?promobenef\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?promos\\.bwin.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?promos\\.fling.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?promote\\.pair.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?promotion-campaigns\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pronetadvertising\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?propellerads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?proranktracker\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?proton-tm\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?protraffic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?provalist\\.info[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?provexia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?provideplant\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?prsitecheck\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ps7894\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?psstt\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pub\\.chez.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pub\\.club-internet.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pub\\.hardware.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pub\\.realmedia.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pubdirecte\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?publicidad\\.elmundo.es[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pubmatic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pubs\\.lemonde.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pushcrew\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?pushengage\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?px\\.dynamicyield.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?q\\.azcentral.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?qctop\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?qnsr\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?quaintcan\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?quantcast\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?quantserve\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?quarterserver\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?questaffiliates\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?quicksandear\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?quigo\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?quinst\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?quisma\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?radar\\.cedexis.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?radarurl\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?radiate\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rampidads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rank-master\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rank-master\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rankchamp\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ranking-charts\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ranking-hits\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ranking-id\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ranking-links\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ranking-liste\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rankingchart\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rankingscout\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rankyou\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rapidcounter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rate\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ratings\\.lycos.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rb1\\.design.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?re-directme\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?reachjunction\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?reactx\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?readgoldfish\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?readserver\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?realcastmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?realclever\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?realclix\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?realmedia-a800\\.d4p.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?realtechnetwork\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?realtracker\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?receptiveink\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?redirectvoluum\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?reduxmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?referralware\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?referrer\\.disqus.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?regnow\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?reinvigorate\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?reklam\\.rfsl.se[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?reklama\\.mironet.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?reklama\\.reflektor.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?reklamcsere\\.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?reklame\\.unwired-i.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?reklamer\\.com.ua[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?relevanz10\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?relmaxtop\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?remarketingpixel\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?remotead\\.cnet.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?remox\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?republika\\.onet.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?retargeter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?revcontent\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?revenue\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?revenuedirect\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?revsci\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?revstats\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?richmails\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?richmedia\\.yimg.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?richwebmaster\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rightstats\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rlcdn\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rle\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rmads\\.msn.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rmedia\\.boston.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?roar\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?robotreplay\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?roia\\.biz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rok\\.com.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rose\\.ixbt.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rotabanner\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?roxr\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rtbpop\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rtbpopd\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rtmark\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ru-traffic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ru4\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rubiconproject\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rulerabbit\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?runads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?rundsp\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?s\\.adroll.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?s2d6\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sageanalyst\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sail-horizon\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?samsungacr\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?samsungads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?saysidewalk\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sbx\\.pagesjaunes.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?scambiobanner\\.aruba.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?scanscout\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?scarcestream\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?scopelight\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?scorecardresearch\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?scratch2cash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?scripte-monster\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?scrubsky\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?scrubswim\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?searchfeast\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?searchmarketing\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?searchramp\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?secure\\.webconnect.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sedoparking\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sedotracker\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sendmepixel\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sensismediasmart\\.com.au[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?separatesilver\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?serv0\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?servedby-buysellads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?servedbyadbutler\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?servedbyopenx\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?servethis\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?services\\.hearstmags.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?serving-sys\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sexcounter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sexinyourcity\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sexlist\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sextracker\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sexystat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?shakesea\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?shakytaste\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?shareadspace\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?shareasale\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sharepointads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sharethrough\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?shelterstraw\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sher\\.index.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?shinystat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?shinystat\\.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?shiveringsail\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?shockingswing\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?shoppingads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sidebar\\.angelfire.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?simpli\\.fi[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?simplisticnose\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sinoa\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sitemeter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sitestat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?siteverification\\.online[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sixsigmatraffic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?skimresources\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?skylink\\.vn[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?slickaffiliate\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?slopeaota\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?smart\\.brvaffs.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?smart4ads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?smartadserver\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?smartlook\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?smetrics\\.walgreens.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?smowtion\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?snakesort\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?snapads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sneaklevel\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sneakystamp\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?snoobi\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?socialspark\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?softclick\\.com.br[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?somniture\\.stuff.co.nz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sonobi\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sortable\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?spacash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sparkstudios\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?specially4u\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?specificmedia\\.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?specificpop\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?spectacularsnail\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?speedomizer\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?speedshiftmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?spezialreporte\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?spillvacation\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?spinbox\\.techtracker.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?spinbox\\.versiontracker.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sponsorads\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sponsorpro\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sponsors\\.thoughtsmedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?spot\\.fitness.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?spotxchange\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?spykemediatrack\\.co[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?spykemediatrack\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?spylog\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?spywarelabs\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?spywarenuker\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?spywords\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?squeamishscarecrow\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?srwww1\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?starffa\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?start\\.freeze.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stat\\.cliche.se[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stat\\.dealtime.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stat\\.dyna.ultraweb.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stat\\.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stat\\.webmedia.pl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stat\\.zenon.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stat24\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stat24\\.meta.ua[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?statcounter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?static\\.fmpub.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?static\\.itrack.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?staticads\\.btopenworld.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?statistik-gallup\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?statm\\.the-adult-company.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stats\\.blogger.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stats\\.directnic.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stats\\.hyperinzerce.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stats\\.merriam-webster.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stats\\.mirrorfootball.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stats\\.olark.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stats\\.pusher.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stats\\.self.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stats\\.townnews.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stats\\.unwired-i.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stats\\.wordpress.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stats\\.x14.eu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stats2\\.self.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stats4all\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?statsie\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?statxpress\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?steelhouse\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?steelhousemedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stickyadstv\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?storesurprise\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stormyachiever\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stormyshock\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stormysponge\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?straightnest\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?stream4fun\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?strivesidewalk\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?subscribe\\.hearstmags.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?succeedscene\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sugoicounter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sumo\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sumome\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?superclix\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?superficialsink\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?superstats\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?supertop\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?supertop100\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?surfmusik-adserver\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?swan-swan-goose\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?swissadsolutions\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?switchadhub\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?swordfishdc\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?sx\\.trhnt.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?t\\.insigit.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?t\\.pusk.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?taboola\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tacoda\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tagular\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tailsweep\\.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tailsweep\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tailsweep\\.se[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?takru\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tangerinenet\\.biz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tapad\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tapinfluence\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?targad\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?targetingnow\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?targetnet\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?targetpoint\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tatsumi-sys\\.jp[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tcads\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tdxio\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?teads\\.tv[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?techclicks\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?teenrevenue\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?teliad\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?terribleturkey\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?text-link-ads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?textad\\.sexsearch.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?textads\\.biz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?textlinks\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tfag\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?theadhost\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?theads\\.me[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?thebugs\\.ws[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?therapistla\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?therichkids\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?thirdrespect\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?thrnt\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?throattrees\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?thruport\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tia\\.timeinc.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tinybar\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tinypass\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tizers\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tlvmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tnkexchange\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tns-counter\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tntclix\\.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?top-casting-termine\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?top-site-list\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?top\\.list.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?top\\.mail.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?top\\.proext.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?top100-images\\.rambler.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?top100\\.mafia.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?top123\\.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?top20free\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?top90\\.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?topacity\\.info[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?topbarh\\.box.sk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?topbucks\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?topforall\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?topgamesites\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?toplist\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?toplist\\.pornhost.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?toplista\\.mw.hu[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?toplistcity\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?topping\\.com.ua[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?toprebates\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?topsafelist\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?topsearcher\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?topsir\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?topsite\\.lv[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?topsites\\.com.br[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?topstats\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?totemcash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?touchclarity\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?touchclarity\\.natwest.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tour\\.brazzers.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tpnads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tracedesire\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?track\\.adform.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?track\\.anchorfree.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?track\\.dating-4-you.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?track\\.flexlinks.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?track\\.flexlinkspro.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?track\\.gawker.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trackalyzer\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tracker\\.icerocket.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tracker\\.marinsm.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tracking\\.crunchiemedia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tracking\\.gajmp.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tracking\\.internetstores.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tracking101\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trackingsoft\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trackmysales\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tradeadexchange\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tradedoubler\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?traffic-exchange\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?traffic\\.focuusing.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trafficadept\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trafficbalancerouting\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trafficfactory\\.biz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trafficholder\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?traffichunt\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trafficjunky\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trafficleader\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trafficsecrets\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trafficspaces\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trafficstrategies\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trafficswarm\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?traffictrader\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trafficz\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trafficz\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?traffiq\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trafic\\.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?traktrafficflow\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?travis\\.bosscasinos.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trekblue\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trekdata\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trendcounter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trendmd\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trhunt\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tribalfusion\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trickycelery\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tritetongue\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trix\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?trmit\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?truehits\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?truehits1\\.gits.net.th[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?truehits2\\.gits.net.th[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tsyndicate\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tubemogul\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?turn\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tvmtracker\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?twittad\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?tyroo\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?uarating\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ukbanners\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ultimateclixx\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ultramercial\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?unarmedindustry\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?unknowntray\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?unrulymedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?untd\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?unusualtitle\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?urlcash\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?us\\.a1.yimg.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?usapromotravel\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?userreplay\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?userreplay\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?utarget\\.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?utils\\.mediageneral.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?v1\\.cnzz.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?validclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?valuead\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?valueclick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?valueclickmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?valuecommerce\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?valuesponsor\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?variablefitness\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?veille-referencement\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ventivmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?vericlick\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?vertadnet\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?veruta\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?vervewireless\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?viafoura\\.co[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?vibrantmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?video-stats\\.video.google.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?videoadex\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?videoegg\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?vidora\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?view4cash\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?viewpoint\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?visiblemeasures\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?visistat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?visit\\.webhosting.yahoo.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?visitbox\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?visual-pagerank\\.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?visualrevenue\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?voicefive\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?voicevegetable\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?vpon\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?vrs\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?vs\\.tucows.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?vungle\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?warlog\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?watchingthat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?wdads\\.sx.atl.publicus.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?web-stat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?web\\.informer.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?web2\\.deja.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webads\\.co.nz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webads\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webangel\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webcash\\.nl[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webcounter\\.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webcounter\\.goweb.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webgains\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webmaster-partnerprogramme24\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webmasterplan\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webmasterplan\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?weborama\\.fr[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webpower\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webreseau\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webseoanalytics\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?websponsors\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webstat\\.channel4.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webstat\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webstat\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webstats4u\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webtrackerplus\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webtracky\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webtraffic\\.se[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webtraxx\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?webtrendslive\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?werbung\\.meteoxpress.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?wetrack\\.it[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?whaleads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?whenu\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?whispa\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?whoisonline\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?wholesaletraffic\\.info[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?widdit\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?widespace\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?widgetbucks\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?wikia-ads\\.wikia.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?window\\.nixnet.cz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?wintricksbanner\\.googlepages.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?witch-counter\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?wlmarketing\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?wonderlandads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?wondoads\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?woopra\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?worldwide-cash\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?wpnrtnmrewunrtok\\.xyz[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?ws-gateway\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?wtlive\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?www-banner\\.chat.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?www-google-analytics\\.l.google.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?www\\.banner-link.com.br[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?www\\.dnps.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?www\\.kaplanindex.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?www\\.money4exit.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?www\\.photo-ads.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?www1\\.gto-media.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?www8\\.glam.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?wwwpromoter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?x-traceur\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?x6\\.yakiuchi.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?xchange\\.ro[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?xclicks\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?xertive\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?xg4ken\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?xiti\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?xplusone\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?xponsor\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?xq1\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?xtendmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?xtremetop100\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?xxxcounter\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?xxxmyself\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?y\\.ibsys.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?yab-adimages\\.s3.amazonaws.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?yabuka\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?yadro\\.ru[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?yesads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?yesadvertising\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?yieldads\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?yieldlab\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?yieldmanager\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?yieldmanager\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?yieldmo\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?yieldtraffic\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?yldbt\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?yoggrt\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?z5x\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?zangocash\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?zanox-affiliate\\.de[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?zanox\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?zantracker\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?zedo\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?zencudo\\.co.uk[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?zenkreka\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?zenzuu\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?zeus\\.developershed.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?zeusclicks\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?zintext\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?zmedia\\.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?zqtk\\.net[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}},{"action":{"type":"block"},"trigger":{"url-filter":"^[^:]+://+([^:/]+\\.)?zv1\\.november-lax.com[:/]","url-filter-is-case-sensitive":true,"load-type":["third-party"]}}] diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/Info.plist b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/Info.plist new file mode 100644 index 000000000..309870a3e Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/Info.plist differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIA VPN Tunnel b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIA VPN Tunnel new file mode 100755 index 000000000..d02865b0c Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIA VPN Tunnel differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Assets.car b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Assets.car new file mode 100644 index 000000000..25f8a3020 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Assets.car differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Info.plist b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Info.plist new file mode 100644 index 000000000..0896d6b6f Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Info.plist differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib new file mode 100644 index 000000000..782e63cc6 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib new file mode 100644 index 000000000..8232ab814 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib new file mode 100644 index 000000000..b7fc0e162 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib new file mode 100644 index 000000000..50dcfb5e7 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist new file mode 100644 index 000000000..fb8201739 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib new file mode 100644 index 000000000..c2c4aa7ad Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib new file mode 100644 index 000000000..d8a9d70a5 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib new file mode 100644 index 000000000..8ba9b88b5 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib new file mode 100644 index 000000000..64cc2e51b Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib new file mode 100644 index 000000000..17e8c708d Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib new file mode 100644 index 000000000..4a92bd1d6 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib new file mode 100644 index 000000000..5000c5c1e Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib new file mode 100644 index 000000000..bbd696c11 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib new file mode 100644 index 000000000..3ff6637ef Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib new file mode 100644 index 000000000..9087e9150 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..e7dd91219 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib new file mode 100644 index 000000000..e7dd91219 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist new file mode 100644 index 000000000..a6ffe0e5d Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib new file mode 100644 index 000000000..0328b5682 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib new file mode 100644 index 000000000..f984c8279 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..85c0f3668 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib new file mode 100644 index 000000000..85c0f3668 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..f871a40b0 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib new file mode 100644 index 000000000..f871a40b0 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..71abc0b03 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib new file mode 100644 index 000000000..71abc0b03 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..32df7a32a Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib new file mode 100644 index 000000000..32df7a32a Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..87eb0e1cc Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib new file mode 100644 index 000000000..87eb0e1cc Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib new file mode 100644 index 000000000..fba5e5b84 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib new file mode 100644 index 000000000..fba5e5b84 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib new file mode 100644 index 000000000..3a454f116 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib new file mode 100644 index 000000000..3a454f116 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib new file mode 100644 index 000000000..03629a06f Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib new file mode 100644 index 000000000..03629a06f Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib new file mode 100644 index 000000000..f2476efe7 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib new file mode 100644 index 000000000..f2476efe7 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib new file mode 100644 index 000000000..76a131359 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib new file mode 100644 index 000000000..76a131359 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib new file mode 100644 index 000000000..4cbd2e982 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib new file mode 100644 index 000000000..e16ab5e4f Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib new file mode 100644 index 000000000..3496a4bbf Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib new file mode 100644 index 000000000..3496a4bbf Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib new file mode 100644 index 000000000..fcfccf837 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib new file mode 100644 index 000000000..fcfccf837 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory new file mode 100644 index 000000000..37d89a56f Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements new file mode 100644 index 000000000..dbf9d6144 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 new file mode 100644 index 000000000..b99f9a94a Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources new file mode 100644 index 000000000..93086328a --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources @@ -0,0 +1,1991 @@ + + + + + files + + Assets.car + + 8h6Hyf4U9/+JlpRmAN3vBaPEjrw= + + Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + dytHgVNc10hWhKQW+WIDasbWdTU= + + Signup.storyboardc/ConfirmVPNPlanViewController.nib + + OVb1ASokoqm9FsqgYqS4ykOLvTk= + + Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + qEnPzvZ7YJ2malb9v8b6uU1qRtI= + + Signup.storyboardc/GDPRViewController.nib + + BnH89TJFPy09hwlepgmy1qX8w5I= + + Signup.storyboardc/Info.plist + + tvSnglTgEmfEVDs4Pqzq89zCWdk= + + Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + htQTSxHbapTjr/KU4MZ+BReh+fg= + + Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + CJa19sBIiRCsSpkmvlAK9WVgIUc= + + Signup.storyboardc/ShareDataInformationViewController.nib + + DClrKMNBhP7R57XPbVZNLZEkhHY= + + Signup.storyboardc/SignupSuccessViewController.nib + + RII82MT1u8xiVhoF6z8GAPWRauw= + + Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + YpRMevT/Hk92B7qxIoBZNubmhVo= + + Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + bJ8pWQoqUwPJh2R449Z5iB80fgw= + + Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + XIT4vTE0sbcaxPw4Ukcc10AudMU= + + Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + 8QYAr5CSJVq9J2M/WNeKrHxyH4k= + + Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + /KugdZ7rq/us89d7xS8Y4W80uoE= + + Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + lAQN56rjGXobwkMhOfbs34FT+S8= + + Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + Welcome.storyboardc/Info.plist + + /pYtZWavELI0+6nEkTUa0WNFSew= + + Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + QLgeyu0ZVc/lDmyITQfrBSRT2Hk= + + Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + gA8eOIpUQd1BEBgO/w9hDFS+JxU= + + Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + Welcome.storyboardc/LoginViewController.nib/runtime.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + GzhYGB3AyZ0wytBn61POuwdsJ7E= + + Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + sQtUseVfpjT4CFtCBgvBwDjWfQA= + + Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + ar.lproj/Signup.strings + + hash + + KDACaW+muq3Q7S2KFi/tSoBrOA0= + + optional + + + ar.lproj/UI.strings + + hash + + q69blyRGQI14B9CBKT9Rsw4dq0k= + + optional + + + ar.lproj/Welcome.strings + + hash + + BkACZwewt5pWHuYeiW8u/ttymCg= + + optional + + + da.lproj/Signup.strings + + hash + + ImqHeuQyhd4vbb7tX6gDpc0Uws4= + + optional + + + da.lproj/UI.strings + + hash + + JEB6TYMiWHIJ3Fwzv9hwS3X5B9c= + + optional + + + da.lproj/Welcome.strings + + hash + + 0U+OaxIpF3m54GcZw6Rj0FT9IQU= + + optional + + + de.lproj/Signup.strings + + hash + + ULQLCKJ1Tkx5LYNqw+wZAPpz+fc= + + optional + + + de.lproj/UI.strings + + hash + + 1964G9tW/vLUljfWDybLqmj8ovo= + + optional + + + de.lproj/Welcome.strings + + hash + + j/jLkt7lT5WaqzpSmS2HeZ2YT7g= + + optional + + + en.lproj/Signup.strings + + hash + + EZ9QZ7PSibfcWSeEETK4rR/PkKE= + + optional + + + en.lproj/UI.strings + + hash + + 8v4J37YS+jZq3LBvpRfFdfrmOjo= + + optional + + + en.lproj/Welcome.strings + + hash + + BwdYyKtC03avQBNFX31HfqSElzI= + + optional + + + es-MX.lproj/Signup.strings + + hash + + /cuvVUGtYOlubi9pgRpN8GF6eaQ= + + optional + + + es-MX.lproj/UI.strings + + hash + + iiP5bcCQB5ClycQCkVGeHIMUAks= + + optional + + + es-MX.lproj/Welcome.strings + + hash + + lx4/QzIqPJcVTvU4PUA9DuA+iR0= + + optional + + + fr.lproj/Signup.strings + + hash + + vRPh7xNvA8CBlDbvqId98Ppaol4= + + optional + + + fr.lproj/UI.strings + + hash + + IbgvE2UN4PxyRd+exu9NKENUaI0= + + optional + + + fr.lproj/Welcome.strings + + hash + + KoygslQ7+C06O61A0YHLMJPIhd8= + + optional + + + it.lproj/Signup.strings + + hash + + Ed4oYGhilkGVvO6AshjBjzdE+7w= + + optional + + + it.lproj/UI.strings + + hash + + Y50/iDsqGezjtBuqSlPo8jymMAc= + + optional + + + it.lproj/Welcome.strings + + hash + + 8OHVfUCzQp3y5Avt0qvL0KEijp8= + + optional + + + ja.lproj/Signup.strings + + hash + + nNEDjklKvB3EYDy3z/dKvk0Y3Sc= + + optional + + + ja.lproj/UI.strings + + hash + + +2YIistydmlPjDts2u1ROqKtWqI= + + optional + + + ja.lproj/Welcome.strings + + hash + + RbM1jidNxxT0GrCW5Bp4AJ2C10U= + + optional + + + ko.lproj/Signup.strings + + hash + + v+qEVshU1lPCEIX6p/5VNVvHCsE= + + optional + + + ko.lproj/UI.strings + + hash + + XSewfIvou+2vfPzfd4L1JobLejU= + + optional + + + ko.lproj/Welcome.strings + + hash + + j/ZhhE8EhAk/Lumf0d8hAl0mnM0= + + optional + + + nb.lproj/Signup.strings + + hash + + KhJ/QqRfNp4OZfzpif4GtcBF8bI= + + optional + + + nb.lproj/UI.strings + + hash + + xDMWYimFFDfSHhe2YZpdtrl2g8k= + + optional + + + nb.lproj/Welcome.strings + + hash + + uwWBmqf4ftnCEhc6CREp8ByROW4= + + optional + + + nl.lproj/Signup.strings + + hash + + NyXHmGW4hA/Eauh4ij9O5S5WhTA= + + optional + + + nl.lproj/UI.strings + + hash + + YZpZdbu3r3xtH/jvKMalDSa3lOc= + + optional + + + nl.lproj/Welcome.strings + + hash + + yqehLrthKrrux3wlT4BXD2o86VM= + + optional + + + pl.lproj/Signup.strings + + hash + + 6OMfwEOtzCuZV03uZytGep2fVcM= + + optional + + + pl.lproj/UI.strings + + hash + + K6FfGb4sRyZ+8fUCnq80qKRGipc= + + optional + + + pl.lproj/Welcome.strings + + hash + + jdPps229/rIXz+/ddHNG9FuKBhQ= + + optional + + + pt-BR.lproj/Signup.strings + + hash + + fbM6TjAWhkqwQRqlFgXqxwrx+8k= + + optional + + + pt-BR.lproj/UI.strings + + hash + + 5JKfMEQAm3AUcBKlsob0yfJRkQk= + + optional + + + pt-BR.lproj/Welcome.strings + + hash + + 01ji1w1oANjR7h5TRr6cBlyaRGo= + + optional + + + ru.lproj/Signup.strings + + hash + + ZPLrICgFyE180EQFQQsAPW2T0LY= + + optional + + + ru.lproj/UI.strings + + hash + + Ke55XO9cpqEQhKUHTr3HEvi0aUM= + + optional + + + ru.lproj/Welcome.strings + + hash + + rfmjmvw733cPOhxZ0RizNQfXkSE= + + optional + + + th.lproj/Signup.strings + + hash + + awJpWTrrqH31sd1t1ndiEy4cN/A= + + optional + + + th.lproj/UI.strings + + hash + + QMaBIt1A8kjNOstov8L0lchT5Ec= + + optional + + + th.lproj/Welcome.strings + + hash + + 5J5E4i04UUqsWy3SQZN1zcKIZaQ= + + optional + + + tr.lproj/Signup.strings + + hash + + 55QLf0o5XG8IWfXbQ6KvFWToA+4= + + optional + + + tr.lproj/UI.strings + + hash + + hfdFuAQLTfdHleeMkh4YCtlcNBY= + + optional + + + tr.lproj/Welcome.strings + + hash + + R49azaTbZXexzZ4fO2KAO8IQIW4= + + optional + + + zh-Hans.lproj/Signup.strings + + hash + + B3OiNtJOoqFlNs77EeQh3/YlwiU= + + optional + + + zh-Hans.lproj/UI.strings + + hash + + athEoNydnFVAkLxqKvlUTv5EfZg= + + optional + + + zh-Hans.lproj/Welcome.strings + + hash + + 6aHDe64C6X+IcTDg3C39b+SM9Ls= + + optional + + + zh-Hant.lproj/Signup.strings + + hash + + InQh2yXFC6brp+xf2gtnVDZtsuY= + + optional + + + zh-Hant.lproj/UI.strings + + hash + + 7NuRLJG/PUbRlsl/6dZTfboVNfQ= + + optional + + + zh-Hant.lproj/Welcome.strings + + hash + + hBHKqa7nicnE6j15W8iBNQQdsws= + + optional + + + + files2 + + Assets.car + + hash + + 8h6Hyf4U9/+JlpRmAN3vBaPEjrw= + + hash2 + + z2oHVz8/itmR3oqHY51lv6NTMX9epuIIiBsUG+B3f3M= + + + Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + hash + + dytHgVNc10hWhKQW+WIDasbWdTU= + + hash2 + + EHhu+ZyC8bLdGTREBf6He41YqGou0HpQDQ4u1t+B67c= + + + Signup.storyboardc/ConfirmVPNPlanViewController.nib + + hash + + OVb1ASokoqm9FsqgYqS4ykOLvTk= + + hash2 + + Rr/ex+JnT00WjY8BTVZWRNqz/GfU4jaR3v03FmrukIA= + + + Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + hash + + qEnPzvZ7YJ2malb9v8b6uU1qRtI= + + hash2 + + fkNfOkKA9R7NGpPPFiVhuYQ2+AdSVeR9osgZyyAms58= + + + Signup.storyboardc/GDPRViewController.nib + + hash + + BnH89TJFPy09hwlepgmy1qX8w5I= + + hash2 + + hDcEgabY8XWIV+bMHjY9T2LEXhXGYAjSsL1LyHygu1A= + + + Signup.storyboardc/Info.plist + + hash + + tvSnglTgEmfEVDs4Pqzq89zCWdk= + + hash2 + + +ULlbQDKRqZAgLPRQ4aWV271svAlSIpTvPj8fAxklSA= + + + Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + hash + + htQTSxHbapTjr/KU4MZ+BReh+fg= + + hash2 + + vqbeJEql0Jgydj1T24xy6xJbrXkBGPmYusMqnTCSGcM= + + + Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + hash + + CJa19sBIiRCsSpkmvlAK9WVgIUc= + + hash2 + + 28vreA7cNtWCBn0Hh2oGxsleKe0mqFxApasYvvlSWTo= + + + Signup.storyboardc/ShareDataInformationViewController.nib + + hash + + DClrKMNBhP7R57XPbVZNLZEkhHY= + + hash2 + + FLZ/2WLEaK53aWKIJqX9T7ltNA15ERKTr7oZHeg14vU= + + + Signup.storyboardc/SignupSuccessViewController.nib + + hash + + RII82MT1u8xiVhoF6z8GAPWRauw= + + hash2 + + 7XhIk/s4X/sIr5xEWP1PVGI7EV+vDS5HktrZ/OskXUk= + + + Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + hash + + YpRMevT/Hk92B7qxIoBZNubmhVo= + + hash2 + + N91d6/YhJJHCGX6EQSKWaoeSLBzL4sitnyKgo7IerzU= + + + Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + hash + + bJ8pWQoqUwPJh2R449Z5iB80fgw= + + hash2 + + LmfITndcyawR5vC3q1+ZA3Tmezvc/H/UOm9eNi8rkXQ= + + + Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + hash + + XIT4vTE0sbcaxPw4Ukcc10AudMU= + + hash2 + + cxj3iSMzDtgAEjJCn2Kh4wOxq643eP+NVKmuyRy4ScE= + + + Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + hash + + 8QYAr5CSJVq9J2M/WNeKrHxyH4k= + + hash2 + + +pb1yeNeVETkzR3D7bHHd7b/7ckHANG2FYkou4fexeA= + + + Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + hash + + /KugdZ7rq/us89d7xS8Y4W80uoE= + + hash2 + + LcuEIHcg/ABNnzlBcFJUh1QnZG6OeeODUinCRME6gVM= + + + Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + hash + + lAQN56rjGXobwkMhOfbs34FT+S8= + + hash2 + + 2sqAv9sKlmNLJyLvObb9ssgf6q3St0BYeyc41iKo10w= + + + Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + hash + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + hash + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + Welcome.storyboardc/Info.plist + + hash + + /pYtZWavELI0+6nEkTUa0WNFSew= + + hash2 + + Y3Hpojl68zniB+aUL9PZXEVKtWuzsnlbS5/xAZKFhAo= + + + Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + hash + + QLgeyu0ZVc/lDmyITQfrBSRT2Hk= + + hash2 + + rvJVcZPH3KzWKHiwzq/TcFc5ZloThq9gqavWaC6uX0s= + + + Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + hash + + gA8eOIpUQd1BEBgO/w9hDFS+JxU= + + hash2 + + 7V3P3q8VYMDAWwvrjqD85I4/kwFbGlegJ76JkMn8sDc= + + + Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + hash + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + Welcome.storyboardc/LoginViewController.nib/runtime.nib + + hash + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + hash + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + hash + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + hash + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + hash + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + hash + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + hash + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + hash + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + hash + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + hash + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + hash + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + hash + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + hash + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + hash + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + hash + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + hash + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + hash + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + hash + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + hash + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + hash + + GzhYGB3AyZ0wytBn61POuwdsJ7E= + + hash2 + + ZXVhR7A3IzlBTiK3AT8wLUDQeJhM59ywT6AJJWSHNuE= + + + Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + hash + + sQtUseVfpjT4CFtCBgvBwDjWfQA= + + hash2 + + gE07Q/56h7roPAuaRZhMhxJ+wNhM0gvRduQ2/Him9z8= + + + Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + hash + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + hash + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + hash + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + hash + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + ar.lproj/Signup.strings + + hash + + KDACaW+muq3Q7S2KFi/tSoBrOA0= + + hash2 + + /PdaPdFVdwwWy0WMwLSdWCQv9CkI1tpm2JyG/6Tmn9M= + + optional + + + ar.lproj/UI.strings + + hash + + q69blyRGQI14B9CBKT9Rsw4dq0k= + + hash2 + + YhKnZ6a5ITfwAgnv/6Cd1x+TPQ067/rO+K+rWNEzD6w= + + optional + + + ar.lproj/Welcome.strings + + hash + + BkACZwewt5pWHuYeiW8u/ttymCg= + + hash2 + + S1/lODt2iX9EyVMvBt0dsAV6rYE8BdXAlCaTa1+HTsw= + + optional + + + da.lproj/Signup.strings + + hash + + ImqHeuQyhd4vbb7tX6gDpc0Uws4= + + hash2 + + +bSgSn+Mt62wraeSALDwHwkp4db5Q4ig2thAObbQPnc= + + optional + + + da.lproj/UI.strings + + hash + + JEB6TYMiWHIJ3Fwzv9hwS3X5B9c= + + hash2 + + doJ3NS9+wFy5hCKe75hwGTA8tafBSrCQJnnrwcghQQs= + + optional + + + da.lproj/Welcome.strings + + hash + + 0U+OaxIpF3m54GcZw6Rj0FT9IQU= + + hash2 + + udZzYVGokipS7z20EPQUqoeoTxmet5LGclYicXo/Qzc= + + optional + + + de.lproj/Signup.strings + + hash + + ULQLCKJ1Tkx5LYNqw+wZAPpz+fc= + + hash2 + + 3qf/FrW+/u8t/lO9wA/+NtfCBtCJ1WguXGz2uvwUoc0= + + optional + + + de.lproj/UI.strings + + hash + + 1964G9tW/vLUljfWDybLqmj8ovo= + + hash2 + + OqXvZaKPjVRbECIamvYeVtO1k5SXy41xBrfoDBODJzU= + + optional + + + de.lproj/Welcome.strings + + hash + + j/jLkt7lT5WaqzpSmS2HeZ2YT7g= + + hash2 + + /RCU9b12hOYxRv0uKqNRMyGNoOs2qGmTkLw0Js7xFcQ= + + optional + + + en.lproj/Signup.strings + + hash + + EZ9QZ7PSibfcWSeEETK4rR/PkKE= + + hash2 + + eTcLQYTr4H9oZFv0rxYaq3gQ+WhpLjFnSyzwaOIiehc= + + optional + + + en.lproj/UI.strings + + hash + + 8v4J37YS+jZq3LBvpRfFdfrmOjo= + + hash2 + + 2LmfTdHJMvlivEZbaU9xSJAAnvlpBpvBa+WumfJ+Zbs= + + optional + + + en.lproj/Welcome.strings + + hash + + BwdYyKtC03avQBNFX31HfqSElzI= + + hash2 + + oAZWhsRhLpQkW9ZhuKf4MOb41w5Y8MZPZx3S0NMM5tk= + + optional + + + es-MX.lproj/Signup.strings + + hash + + /cuvVUGtYOlubi9pgRpN8GF6eaQ= + + hash2 + + nI1MegvByIjofRyKN8F43cuCTWoXr5uIExtoQ3BK6NM= + + optional + + + es-MX.lproj/UI.strings + + hash + + iiP5bcCQB5ClycQCkVGeHIMUAks= + + hash2 + + a8Vp2K22QfOvNgn1DCjRhoTHkZVdwywOmftje9rC42Y= + + optional + + + es-MX.lproj/Welcome.strings + + hash + + lx4/QzIqPJcVTvU4PUA9DuA+iR0= + + hash2 + + mxe8YvU0Z6ToCEE2d86cOJNrmOVz8cRCJpBzDQWLVWc= + + optional + + + fr.lproj/Signup.strings + + hash + + vRPh7xNvA8CBlDbvqId98Ppaol4= + + hash2 + + QqrxBLWpNYv5rrqBFN8BLC6LNXUmQVa74Gl+0ksKBZU= + + optional + + + fr.lproj/UI.strings + + hash + + IbgvE2UN4PxyRd+exu9NKENUaI0= + + hash2 + + Pv8eZpPXvR5mqm53bwD8agrzEaWy3xj6YdWgIOflm+M= + + optional + + + fr.lproj/Welcome.strings + + hash + + KoygslQ7+C06O61A0YHLMJPIhd8= + + hash2 + + xyVMkl7jhNBZ/vN0ZFmM2FlY8ovTdbitINQqEgRyqks= + + optional + + + it.lproj/Signup.strings + + hash + + Ed4oYGhilkGVvO6AshjBjzdE+7w= + + hash2 + + VlWjS5dJ4UNfaNhHqlxeKfkECiko5YzTss4+zOmzYJ4= + + optional + + + it.lproj/UI.strings + + hash + + Y50/iDsqGezjtBuqSlPo8jymMAc= + + hash2 + + y2JDFhY4F9hvHbr4F4pF6PrFuy4JUyVFpMw8BcbSBY4= + + optional + + + it.lproj/Welcome.strings + + hash + + 8OHVfUCzQp3y5Avt0qvL0KEijp8= + + hash2 + + lu+ZwHtxRo9m+9fmCbojh8YbdagKuR6eYwXH/O4QNHo= + + optional + + + ja.lproj/Signup.strings + + hash + + nNEDjklKvB3EYDy3z/dKvk0Y3Sc= + + hash2 + + bDq3nM4T1ut8Ts8+QYkxdWNGRu+//zSf189mi3aRlQ8= + + optional + + + ja.lproj/UI.strings + + hash + + +2YIistydmlPjDts2u1ROqKtWqI= + + hash2 + + YaeZ3JgOA+qIusYRqxxG6pwBkrFim1rw7qTyLnl060I= + + optional + + + ja.lproj/Welcome.strings + + hash + + RbM1jidNxxT0GrCW5Bp4AJ2C10U= + + hash2 + + Xq2cl5IrUxxaYjKRRxrCcWp8u2KzQtjBAPMG2ywwICA= + + optional + + + ko.lproj/Signup.strings + + hash + + v+qEVshU1lPCEIX6p/5VNVvHCsE= + + hash2 + + tGa6ibOVYp6N7/L++jdOleoT9KE1QQ1PK1rhzpVOKDQ= + + optional + + + ko.lproj/UI.strings + + hash + + XSewfIvou+2vfPzfd4L1JobLejU= + + hash2 + + QIUwyVItXRoQKXGmgHFFotXmiOSE9JxkZlaoE2IHX+8= + + optional + + + ko.lproj/Welcome.strings + + hash + + j/ZhhE8EhAk/Lumf0d8hAl0mnM0= + + hash2 + + weQQxyn+b2SpWKeGAvJqE/ii7MCRaDRxNADg8r9TvYI= + + optional + + + nb.lproj/Signup.strings + + hash + + KhJ/QqRfNp4OZfzpif4GtcBF8bI= + + hash2 + + RnLEv00iw5lOIGL/XJzJU1ShBwn9hBnC4hNhikuyhA4= + + optional + + + nb.lproj/UI.strings + + hash + + xDMWYimFFDfSHhe2YZpdtrl2g8k= + + hash2 + + CbdEeBsje8P4+h3x6IQ57ZROUQ898FBunnH3ZY69DnQ= + + optional + + + nb.lproj/Welcome.strings + + hash + + uwWBmqf4ftnCEhc6CREp8ByROW4= + + hash2 + + 3l4+0NbmewoK9l0/qdkIGPcqqrLIRM5eOrwPHGkUEy0= + + optional + + + nl.lproj/Signup.strings + + hash + + NyXHmGW4hA/Eauh4ij9O5S5WhTA= + + hash2 + + VfV2uL8OKA5ZiR3yiHFT65ZEHaCbkn35Yo+ur18Bqxw= + + optional + + + nl.lproj/UI.strings + + hash + + YZpZdbu3r3xtH/jvKMalDSa3lOc= + + hash2 + + 69DUk8Zeh5SReiVA+Wk9iHozzU98pp8V8uFeG+EA+A0= + + optional + + + nl.lproj/Welcome.strings + + hash + + yqehLrthKrrux3wlT4BXD2o86VM= + + hash2 + + LHqIVFxiS7xOGRDl+Mc94nzpdWHZpV7V+YNrcO3F6rw= + + optional + + + pl.lproj/Signup.strings + + hash + + 6OMfwEOtzCuZV03uZytGep2fVcM= + + hash2 + + me1r0CSvQxGrjhri1zbZY30vF6XWxdoV5q/XNHlGVhs= + + optional + + + pl.lproj/UI.strings + + hash + + K6FfGb4sRyZ+8fUCnq80qKRGipc= + + hash2 + + frs+aVxqmI1A7qNQ3lTqmaN+e68SScT1D6TutOPSHFs= + + optional + + + pl.lproj/Welcome.strings + + hash + + jdPps229/rIXz+/ddHNG9FuKBhQ= + + hash2 + + xQJW7uzg6y9kJf1gLZnCM9oO+0wQ84AayU+o+TV5Y2I= + + optional + + + pt-BR.lproj/Signup.strings + + hash + + fbM6TjAWhkqwQRqlFgXqxwrx+8k= + + hash2 + + MnV7VMLXWFm/KNE5a8UHkxR04f0OznpqoK1+9hyw8zY= + + optional + + + pt-BR.lproj/UI.strings + + hash + + 5JKfMEQAm3AUcBKlsob0yfJRkQk= + + hash2 + + DxvjdPIJCkbOywZjS5+ayQkGKWHlrGcquTxizAdezyg= + + optional + + + pt-BR.lproj/Welcome.strings + + hash + + 01ji1w1oANjR7h5TRr6cBlyaRGo= + + hash2 + + LDC5bZkG2h8AgTQLoL1yMj6JJA/ir2Qs9YoX0A27QLc= + + optional + + + ru.lproj/Signup.strings + + hash + + ZPLrICgFyE180EQFQQsAPW2T0LY= + + hash2 + + WWOM/zJIvlgQASAWOk/VrhJ76xkmJSNIM383qyAebmY= + + optional + + + ru.lproj/UI.strings + + hash + + Ke55XO9cpqEQhKUHTr3HEvi0aUM= + + hash2 + + oSkpUWDyzNoWL+/tE+JqlzA0l5XGRGrg0sa5Gvpc4eA= + + optional + + + ru.lproj/Welcome.strings + + hash + + rfmjmvw733cPOhxZ0RizNQfXkSE= + + hash2 + + NeG7RvpFs7aBDoclE4CeSnfGf9AS7tGvjGr/m1zT3eY= + + optional + + + th.lproj/Signup.strings + + hash + + awJpWTrrqH31sd1t1ndiEy4cN/A= + + hash2 + + buuAYnSRdzIW7wnFAfyIoc2xNnPeH6VmMpaTl1UnDcI= + + optional + + + th.lproj/UI.strings + + hash + + QMaBIt1A8kjNOstov8L0lchT5Ec= + + hash2 + + 86j7ej1K8vjK2Wc+4VvI8COo0F5VNrFgab6jFb52UQM= + + optional + + + th.lproj/Welcome.strings + + hash + + 5J5E4i04UUqsWy3SQZN1zcKIZaQ= + + hash2 + + CWB5kJ7tdPh65LpMEk7ON91tZXYPjCLHG3+KYt/Wor8= + + optional + + + tr.lproj/Signup.strings + + hash + + 55QLf0o5XG8IWfXbQ6KvFWToA+4= + + hash2 + + J7rTcADNQWVMdE7ToyJl5ztWFP7nS0LpgiIcVb4D/H8= + + optional + + + tr.lproj/UI.strings + + hash + + hfdFuAQLTfdHleeMkh4YCtlcNBY= + + hash2 + + mn9KO/anRw5JkawqXZT06MvC8pSCiTjPxNb+c3RrZ1I= + + optional + + + tr.lproj/Welcome.strings + + hash + + R49azaTbZXexzZ4fO2KAO8IQIW4= + + hash2 + + 3U8T+edoinqQskEd4Y8vg0sVEFsjDRp4YCrhcTIq0Nw= + + optional + + + zh-Hans.lproj/Signup.strings + + hash + + B3OiNtJOoqFlNs77EeQh3/YlwiU= + + hash2 + + 92+yGo0u+BgXiVmoYH9vE1wxCXffUp20Eb5V8JkLJDU= + + optional + + + zh-Hans.lproj/UI.strings + + hash + + athEoNydnFVAkLxqKvlUTv5EfZg= + + hash2 + + iDsYoUTxx8POedODQmaipEBJukmHm0klpri/JSYxzCg= + + optional + + + zh-Hans.lproj/Welcome.strings + + hash + + 6aHDe64C6X+IcTDg3C39b+SM9Ls= + + hash2 + + NtHmRVKzAicr7H8AVAqK8Bni236Z2cMnLjdcG/U7T6M= + + optional + + + zh-Hant.lproj/Signup.strings + + hash + + InQh2yXFC6brp+xf2gtnVDZtsuY= + + hash2 + + ajON8rkioyflp0u9oIDFniyq4zryBG0tC/51c7OOzbY= + + optional + + + zh-Hant.lproj/UI.strings + + hash + + 7NuRLJG/PUbRlsl/6dZTfboVNfQ= + + hash2 + + IvX18xiU0gageVb9uJLXqnoj5htrqNqSWI1LCqnTWY0= + + optional + + + zh-Hant.lproj/Welcome.strings + + hash + + hBHKqa7nicnE6j15W8iBNQQdsws= + + hash2 + + E7PBBBbQdDJESlMtJW1vcQ17At7XbJBTHK0Mbm0eyU0= + + optional + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature new file mode 100644 index 000000000..e69de29bb diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings new file mode 100644 index 000000000..ce7d9f39d --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "تأكيد التسجيل"; +"in_progress.message" = "جارٍ تأكيد عملية الشراء مع نظامنا. يمكن أن يستغرق ذلك لحظة لذلك انتظر قليلًا."; +"in_progress.redeem.message" = "جارٍ تأكيد رمز بطاقتك مع نظامنا. قد يستغرق ذلك بضع لحظات، انتظر قليلًا."; + +"success.title" = "تم الشراء"; +"success.message_format" = "شضكراً على اشتراكك معنا. لقد أرسلنا اسم المستخدم وكلمة المرور الخاصين بك إلى بريدك الإلكتروني %@"; +"success.redeem.title" = "تم استبدال البطاقة بنجاح"; +"success.redeem.message" = "ستصلك رسالة عبر البريد الإلكتروني تتضمن اسم المستخدم وكلمة المرور.\n\nتفاصيل تسجيل الدخول"; +"success.username.caption" = "اسم المستخدم"; +"success.password.caption" = "كلمة المرور"; +"success.submit" = "كيف تبدأ"; + +"failure.vc_title" = "فشل تسجيل الآن"; +"failure.title" = "فشل إنشاء الحساب"; +"failure.message" = "يتعذر علينا إنشاء حساب في الوقت الحالي. يرجى إعادة المحاولة لاحقًا. \n\nعند إعادة فتح التطبيق سيتم إعادة محاولة إنشاء حساب."; +"failure.purchase.sandbox.message" = "اشتراك الصندوق المحدد غير متاح في الإنتاج."; +"failure.redeem.invalid.title" = "رمز بطاقة غير صالح"; +"failure.redeem.invalid.message" = "يبدو أنك أدخلت رمز بطاقة غير صالح. يرجى إعادة المحاولة."; +"failure.redeem.claimed.title" = "تم استخدام هذه البطاقة بالفعل"; +"failure.redeem.claimed.message" = "يبدو أن هذه البطاقة استُخدمت في حساب آخر. حاول إدخال رمز جديد."; +"failure.submit" = "عودة"; + +"unreachable.vc_title" = "خطأ"; +"unreachable.title" = "أوبس!"; +"unreachable.message" = "لم يتم العثور على اتصال بالإنترنت. يرجى التأكد من اتصالك بالإنترنت وضغط زر إعادة المحاولة أدناه.\n\nيمكنك العودة إلى التطبيق في وقت لاحق لإنهاء العملية."; +"unreachable.submit" = "أعد المحاولة"; + +"purchase.uncredited.alert.message" = "لديك معاملات غير معتمدة. هل تريد استعادة تفاصيل حسابك؟"; +"purchase.uncredited.alert.button.cancel" = "إلغاء"; +"purchase.uncredited.alert.button.recover" = "استعادة الحساب"; + +"purchase.trials.intro" = "ابدأ تجربتك المجانية لمدة 7 ايام"; +"purchase.trials.price.after" = "ثم %@"; +"purchase.trials.money.back" = "ضمان استرداد المال لمدة 30 أيام"; +"purchase.trials.1year.protection" = "1 سنة من الخصوصية وحماية الهوية"; +"purchase.trials.anonymous" = "تصفح مجهول الهوية وإخفاء عنوان IP."; +"purchase.trials.devices" = "يدعم 10 أجهزة في المرة الواحدة"; +"purchase.trials.devices.description" = "احمي نفسك على ما يصل إلى 10 أجهزة في وقت واحد."; +"purchase.trials.region" = "اتصل بأي منطقة بسهولة"; +"purchase.trials.servers" = "أكثر من 3300 خادم في 32 دولة"; +"purchase.trials.start" = "ابدأ الاشتراك"; +"purchase.trials.all.plans" = "مشاهدة جميع الخطط المتاحة"; + +"purchase.subscribe.now" = "اشتراك الآن"; + +// WALKTHROUGH + +"walkthrough.action.next" = "التالي"; +"walkthrough.action.done" = "تم"; +"walkthrough.action.skip" = "تخطي"; + +"walkthrough.page.1.title" = "يدعم 10 أجهزة في المرة الواحدة"; +"walkthrough.page.1.description" = "احمي نفسك على ما يصل إلى 10 أجهزة في وقت واحد."; +"walkthrough.page.2.title" = "اتصل بأي منطقة بسهولة"; +"walkthrough.page.2.description" = "مع خوادم في جميع أنحاء العالم، أنت دائما تحت الحماية."; +"walkthrough.page.3.title" = "احمي نفسك من الإعلانات"; +"walkthrough.page.3.description" = "تمكين ميزة حظر المحتوى يمنع الإعلانات من الظهور في Safari."; + +"share.data.buttons.accept" = "قبول"; +"share.data.buttons.noThanks" = "لا، شكرًا"; +"share.data.buttons.readMore" = "قراءة المزيد"; +"share.data.text.title" = "يرجى مساعدتنا في تحسين خدمتنا"; +"share.data.text.description" = "لمساعدتنا في ضمان أداء اتصال خدمتنا، يمكنك مشاركة إحصائيات اتصالك معنا دون الكشف عن هويتك. لا تتضمن هذه التقارير أي معلومات محددة للشخصية."; +"share.data.text.footer" = "يمكنك دائمًا التحكم في ذلك من إعداداتك"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings new file mode 100644 index 000000000..d93d9b375 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "الإصدار %@ (%@)"; +"global.close" = "إغلاق"; +"global.ok" = "موافق"; +"global.cancel" = "إلغاء"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings new file mode 100644 index 000000000..75d5562b2 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "سجل الدخول إلى حسابك"; +"login.username.placeholder" = "اسم المستخدم (p1234567)"; +"login.password.placeholder" = "كلمة المرور"; +"login.submit" = "تسجيل الدخول"; +"login.restore.button" = "لم تحصل على تفاصيل الحساب؟"; +"login.error.title" = "تسجيل الدخول"; +"login.error.validation" = "يجب إدخال اسم المستخدم وكلمة المرور"; +"login.error.unauthorized" = "اسم المستخدم أو كلمة المرور غير صحيحة."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "تسجيل الدخول باستخدام إيصال الشراء"; +"login.magic.link.title" = "تسجيل الدخول باستخدام رابط البريد الإلكتروني السحري"; +"login.magic.link.response" = "يرجى إلقاء نظرة على بريدك الإلكتروني للحصول على رابط تسجيل الدخول."; +"login.magic.link.send" = "إرسال الرابط"; +"login.magic.link.invalid.email" = "البريد الإلكتروني غير صحيح. يرجى إعادة المحاولة."; + +"purchase.title" = "حدد خطة VPN"; +"purchase.subtitle" = "ضمان استرداد المال لمدة 7 أيام"; +"purchase.email.placeholder" = "البريد الإلكتروني"; +"purchase.continue" = "متابعة"; +"purchase.login.footer" = "لديك حساب بالفعل؟"; +"purchase.login.button" = "تسجيل الدخول"; +"purchase.error.title" = "شراء"; +"purchase.error.validation" = "يجب إدخال عنوان بريد إلكتروني."; +"purchase.error.connectivity.title" = "فشل الاتصال"; +"purchase.error.connectivity.description" = "لم نتمكن من الوصول إلى منفذ الإنترنت الخاص. ربما بسبب اتصال ضعيف بالإنترنت أو خدماتنا موقوفة في بلدك."; +"purchase.confirm.form.email" = "يرجى إدخال بريدك الإلكتروني"; +"purchase.confirm.plan" = "أنت تشتري الآن خطة %@"; +"purchase.email.why" = "نحتاج إلى بريدك الإلكتروني لإرسال اسم المستخدم وكلمة المرور."; +"purchase.submit" = "إرسال"; +"purchase.or" = "أو"; + +"upgrade.header" = "مرحبًا بعودتك!"; +"upgrade.title" = "لاستخدام Private Internet Access، تحتاج إلى تجديد اشتراكك."; +"upgrade.renew.now" = "تجديد الآن"; + + + +"redeem.title" = "استلم محتويات بطاقة هدية"; +"redeem.subtitle" = "أدخل بريدك الإلكتروني ورمز بطاقة الهدية أو بطاقة التجربة المكون من %lu خانات."; +"redeem.email.placeholder" = "البريد الإلكتروني"; +"redeem.submit" = "إرسال"; +"redeem.error.title" = "استلام"; +"redeem.error.code" = "يجب أن يتكون الرمز من %lu خانات رقمية."; +"redeem.error.allfields" = "يرجى كتابة بريدك الإلكتروني ورمز PIN الخاص بالبطاقة."; +"redeem.accessibility.back" = "عودة"; +"redeem.giftcard.placeholder" = "رمز PIN الخاص بالبطاقة."; + +"plan.monthly.title" = "شهريًا"; +"plan.yearly.title" = "سنويًا"; +"plan.yearly.detail_format" = "%@%@ في السنة"; +"plan.price_format" = "%@ / شهر"; +"plan.best_value" = "أفضل قيمة"; +"plan.accessibility.per_month" = "في الشهر"; + +"restore.title" = "استرداد الشراء غير المقيد في الحساب"; +"restore.subtitle" = "إذا اشتريت خطة من خلال هذا التطبيق ولم تصلك بيانات تسجيل دخولك، يمكنك إرسالها مرة أخرى من هنا. لن يتم تحصيل رسوم منك أثناء هذه العملية."; +"restore.email.placeholder" = "البريد الإلكتروني"; +"restore.submit" = "تأكيد"; + +"iap.error.message.unavailable" = "خوادم أبل غير متاحة حاليًا. يرجى إعادة المحاولة لاحقًا."; +"iap.error.title" = "خطأ"; + +"agreement.trials.title" = "شروط وأحكام الفترات التجريبية المجانية"; +"agreement.trials.message" = "سيتم تحصيل مبلغ الدفع من حساب Apple ID الخاص بك عند تأكيد الشراء. يتم تجديد الاشتراك تلقائيًا ما لم يتم إلغاؤه قبل نهاية الفترة الحالية بمدة 24 ساعة على الأقل. سيتم محاسبتك على التجديد خلال 24 ساعة قبل نهاية الفترة الحالية. يمكنك إدارة وإلغاء اشتراكاتك عن طريق الانتقال إلى إعدادات حسابك في متجر التطبيقات بعد الشراء.\n\nقد توفر بعض الاشتراكات المدفوعة فترة تجريبية مجانية قبل تحصيل المبلغ من طريقة الدفع. إذا قررت إلغاء الاشتراك من اشتراك مدفوع قبل البدء في تحصيل الرسوم من طريقة الدفع، قم بإلغاء الاشتراك قبل انتهاء الفترة التجريبية المجانية بمدة 24 ساعة على الأقل.\n\nلا يتم توفير التجارب المجانية إلا للمستخدمين الجدد فقط، وهي وفقًا لتقديرنا الخاص، وإذا حاولت التسجيل للحصول على فترة تجريبية مجانية إضافية، فستتم محاسبتك فورًا على رسوم الاشتراك القياسية.\n\nنحن نحتفظ بالحق في إلغاء الفترة التجريبية المجانية في أي وقت.\n\nسيتم مصادرة أي جزء غير مستخدم من الفترة التجريبية المجانية عند شراء اشتراك.\n\nيمثل التسجيل قبولًا لهذه الشروط والأحكام."; +"agreement.message" = "بعد انتهاء الـ 7 أيام الخاصة بالفترة التجريبية المجانية، يتم تجديد هذا الاشتراك تلقائيًا مقابل %@ ما لم يتم إلغاؤه قبل 24 ساعة على الأقل من نهاية الفترة التجريبية. ستتم محاسبة حساب Apple ID الخاص بك على رسوم التجديد في غضون 24 ساعة قبل نهاية الفترة التجريبية. يمكنك إدارة وإلغاء اشتراكاتك عن طريق الانتقال إلى إعدادات حسابك في App Store بعد الشراء. يقتصر عرض الفترة التجريبية لمدة 7 أيام على عرض فترة تجريبية واحد لمدة 7 أيام لكل مستخدم. أي جزء غير مستخدم من الفترة التجريبية المجانية، إذا تم عرضها، سيتم مصادرته عندما يشتري المستخدم اشتراكًا. تشمل جميع الأسعار ضرائب المبيعات المحلية المطبقة.\n\nيعتبر الاشتراك بمثابة قبول $1 و$2."; +"agreement.trials.yearly.plan" = "سنة"; +"agreement.trials.monthly.plan" = "شهر"; + +"agreement.message.tos" = "شروط الخدمة"; +"agreement.message.privacy" = "سياسة الخصوصية"; + +"getstarted.buttons.buyaccount" = "شراء حساب"; + +"gdpr.collect.data.title" = "المعلومات الشخصية التي نجمعها"; +"gdpr.collect.data.description" = "عنوان البريد الإلكتروني لأغراض إدارة الحساب والحماية من إساءة الاستخدام."; +"gdpr.usage.data.title" = "استخدامات المعلومات الشخصية التي نجمعها"; +"gdpr.usage.data.description" = "يتم استخدام عنوان البريد الإلكتروني لإرسال معلومات الاشتراك وتأكيد الدفع ومراسلات العملاء والعروض الترويجية الخاصة بـ Private Internet Access فقط."; +"gdpr.accept.button.title" = "موافق ومتابعة"; + +"update.account.email.error" = "تعذَّر تعديل البريد الإلكتروني للحساب"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings new file mode 100644 index 000000000..44c000115 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Bekræft tilmelding"; +"in_progress.message" = "Vi bekræfter dit køb i vores system. Det kan tage et øjeblik, så bliv her venligst."; +"in_progress.redeem.message" = "Vi bekræfter din kort-pinkode i vores system. Det kan tage et øjeblik, så bliv her venligst."; + +"success.title" = "Køb fuldført"; +"success.message_format" = "Tak fordi du tilmeldte dig hos os. Vi har sendt dit brugernavn og kodeord til din e-mailadresse %@"; +"success.redeem.title" = "Kort indløst med succes"; +"success.redeem.message" = "Du modtager snart en e-mail med dit brugernavn og adgangskode.\n\nDine loginoplysninger"; +"success.username.caption" = "Brugernavn"; +"success.password.caption" = "Kodeord"; +"success.submit" = "Kom i gang"; + +"failure.vc_title" = "Tilmelding mislykkedes"; +"failure.title" = "Kunne ikke oprette konto"; +"failure.message" = "Vi kan ikke oprette en konto på nuværende tidspunkt. Prøv igen senere.\n\nGenåbning af appen vil genoptage forsøget på at oprette en konto."; +"failure.purchase.sandbox.message" = "Det valgte sandbox-abonnement er ikke tilgængeligt i produktionen."; +"failure.redeem.invalid.title" = "Ugyldig kort-pinkode"; +"failure.redeem.invalid.message" = "Det ser ud til, at du har indtastet en ugyldig kort-pinkode. Prøv igen."; +"failure.redeem.claimed.title" = "Kort allerede taget"; +"failure.redeem.claimed.message" = "Det ser ud til, at dette kort allerede er taget af en anden konto. Prøv at indtaste en anden pinkode."; +"failure.submit" = "GÅ TILBAGE"; + +"unreachable.vc_title" = "Fejl"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Ingen internetforbindelse fundet. Bekræft venligst, at du har en internetforbindelse, og tryk på \"prøv igen\" herunder.\n\nDu kan vende tilbage til appen senere for at afslutte processen."; +"unreachable.submit" = "PRØV IGEN"; + +"purchase.uncredited.alert.message" = "Du har ukrediterede transaktioner. Vil du gendanne dine kontooplysninger?"; +"purchase.uncredited.alert.button.cancel" = "Annuller"; +"purchase.uncredited.alert.button.recover" = "Gendan konto"; + +"purchase.trials.intro" = "Start din 7-dages gratis prøveperiode"; +"purchase.trials.price.after" = "Derefter %@"; +"purchase.trials.money.back" = "30-dages pengene tilbage garanti"; +"purchase.trials.1year.protection" = "1 års beskyttelse af personlige oplysninger og identitet"; +"purchase.trials.anonymous" = "Gennemse anonymt og skjul din ip."; +"purchase.trials.devices" = "Understøtter 10 enheder på én gang"; +"purchase.trials.devices.description" = "Beskyt dig selv på op til 10 enheder ad gangen."; +"purchase.trials.region" = "Forbind nemt til en hvilken som helst region"; +"purchase.trials.servers" = "Mere end 3300 servere i 32 lande"; +"purchase.trials.start" = "Start abonnement"; +"purchase.trials.all.plans" = "Se alle tilgængelige planer"; + +"purchase.subscribe.now" = "Tilmeld nu"; + +// WALKTHROUGH + +"walkthrough.action.next" = "NÆSTE"; +"walkthrough.action.done" = "UDFØRT"; +"walkthrough.action.skip" = "SPRING OVER"; + +"walkthrough.page.1.title" = "Understøtter 10 enheder på en gang"; +"walkthrough.page.1.description" = "Beskyt dig selv på op til 10 enheder ad gangen."; +"walkthrough.page.2.title" = "Forbind nemt til en hvilken som helst region"; +"walkthrough.page.2.description" = "Med servere rundt om i verden er du altid beskyttet."; +"walkthrough.page.3.title" = "Beskyt dig mod annoncer"; +"walkthrough.page.3.description" = "Aktivering af vores Indholdsblokering forhindrer reklamer i at blive vist i Safari."; + +"share.data.buttons.accept" = "Accepter"; +"share.data.buttons.noThanks" = "Nej tak"; +"share.data.buttons.readMore" = "Læs mere"; +"share.data.text.title" = "Hjælp os med at forbedre vores service"; +"share.data.text.description" = "For at hjælpe os med at sikre vores tjenestes forbindelsesydelse, kan du anonymt dele dine forbindelsesstatistikker med os. Disse rapporter inkluderer ikke personligt identificerbare oplysninger."; +"share.data.text.footer" = "Du kan altid kontrollere dette fra dine indstillinger"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/UI.strings new file mode 100644 index 000000000..ef42d7faf --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Luk"; +"global.ok" = "OK"; +"global.cancel" = "Annuller"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings new file mode 100644 index 000000000..6e179a032 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Log ind på din konto"; +"login.username.placeholder" = "Brugernavn (p1234567)"; +"login.password.placeholder" = "Kodeord"; +"login.submit" = "LOG IND"; +"login.restore.button" = "Modtog du ikke dine kontodetaljer?"; +"login.error.title" = "Log ind"; +"login.error.validation" = "Du skal indtaste et brugernavn og et kodeord."; +"login.error.unauthorized" = "Dit brugernavn eller kodeord er forkert."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Log på med købskvittering"; +"login.magic.link.title" = "Log ind ved hjælp af magisk e-maillink"; +"login.magic.link.response" = "Se i din e-mail for et login-link."; +"login.magic.link.send" = "Send link"; +"login.magic.link.invalid.email" = "Ugyldig e-mail. Prøv igen."; + +"purchase.title" = "Vælg en VPN-plan"; +"purchase.subtitle" = "30-dages pengene tilbage garanti"; +"purchase.email.placeholder" = "E-mailadresse"; +"purchase.continue" = "Fortsæt"; +"purchase.login.footer" = "Har du allerede en konto?"; +"purchase.login.button" = "Log ind"; +"purchase.error.title" = "Køb"; +"purchase.error.validation" = "Du skal indtaste en e-mailadresse"; +"purchase.error.connectivity.title" = "Forbindelsesfejl"; +"purchase.error.connectivity.description" = "Vi kan ikke nå Private Internet Access. Dette kan skyldes dårlig internet eller at vores service er blokeret i dit land."; +"purchase.confirm.form.email" = "Indtast din e-mailadresse"; +"purchase.confirm.plan" = "Du køber %@-planen"; +"purchase.email.why" = "Vi har brug for din e-mail for at sende dit brugernavn og din adgangskode."; +"purchase.submit" = "Indsend"; +"purchase.or" = "eller"; + +"upgrade.header" = "Velkommen tilbage!"; +"upgrade.title" = "For at bruge Private Internet Access skal du forny dit abonnement."; +"upgrade.renew.now" = "Forny nu"; + + + +"redeem.title" = "Indløs gavekort"; +"redeem.subtitle" = "Indtast din e-mailadresse, og %lu-cifrede pinkode frra dit gavekort eller prøvekort herunder."; +"redeem.email.placeholder" = "E-mailadresse"; +"redeem.submit" = "INDSEND"; +"redeem.error.title" = "Indløs"; +"redeem.error.code" = "Koden skal være %lu numeriske cifre."; +"redeem.error.allfields" = "Indtast venligst din e-mail og dit korts PIN-kode."; +"redeem.accessibility.back" = "Tilbage"; +"redeem.giftcard.placeholder" = "Gavekortets PIN-kode"; + +"plan.monthly.title" = "Månedligt"; +"plan.yearly.title" = "Årligt"; +"plan.yearly.detail_format" = "%@%@ per år"; +"plan.price_format" = "%@/mdr"; +"plan.best_value" = "Bedste værdi"; +"plan.accessibility.per_month" = "per måned"; + +"restore.title" = "Gendan ukrediteret køb"; +"restore.subtitle" = "Hvis du har købt en plan gennem denne app og ikke har modtaget dine legitimationsoplysninger, kan du anmode om at sende dem igen herfra. Du vil ikke blive opkrævet i løbet af denne proces."; +"restore.email.placeholder" = "E-mailadresse"; +"restore.submit" = "BEKRÆFT"; + +"iap.error.message.unavailable" = "Apple-servere er ikke tilgængelige i øjeblikket. Prøv venligst igen senere."; +"iap.error.title" = "Fejl"; + +"agreement.trials.title" = "Vilkår og betingelser for gratis prøveperioder"; +"agreement.trials.message" = "Betaling debiteres din Apple ID-konto ved bekræftelsen af ​​købet. Abonnementet fornyes automatisk, medmindre det annulleres mindst 24 timer inden udgangen af ​​den aktuelle periode. Din konto bliver debiteret for fornyelse inden for 24 timer inden udgangen af ​​den aktuelle periode. Du kan administrere og annullere dine abonnementer ved at gå til dine kontoindstillinger i App Store efter køb.\n\nVisse betalte abonnementer kan muligvis tilbyde en gratis prøveperiode, inden de opkræver din betalingsmetode. Hvis du beslutter at afmelde dig et betalt abonnement, før vi begynder at opkræve din betalingsmetode, skal du annullere abonnementet mindst 24 timer før den gratis prøveperiode afsluttes.\n\nGratis prøveperioder er kun tilgængelige for nye brugere og er efter vores eget skøn, og hvis du forsøger at tilmelde dig en ekstra gratis prøveperiode, bliver du straks debiteret for det almindelige abonnementsgebyr.\n\nVi forbeholder os retten til at tilbagekalde din gratis prøveperiode til enhver tid.\n\nEnhver ubrugt del af din gratis prøveperiode fortabes ved køb af et abonnement.\n\nTilmelding udgør accept af disse vilkår og betingelser."; +"agreement.message" = "Efter den gratis prøveperiode på 7 dage, fornyes dette abonnement automatisk for %@, medmindre det annulleres mindst 24 timer før prøveperioden er afsluttet. Din Apple ID-konto bliver debiteret for fornyelse inden for 24 timer inden udløbet af prøveperioden. Du kan administrere og annullere dine abonnementer ved at gå til din App Store-kontoindstillinger efter købet. Tilbudet med en 7-dages prøveperiode er begrænset til en 7-dages prøveperiode pr. bruger. Enhver ubrugt del af en gratis prøveperiode, hvis den tilbydes, fortabes, når brugeren køber et abonnement. Alle priser inkluderer gældende lokal moms.\n\nSigning up constitutes acceptance of the $1 and the $2."; +"agreement.trials.yearly.plan" = "år"; +"agreement.trials.monthly.plan" = "måned"; + +"agreement.message.tos" = "Vilkår for brug"; +"agreement.message.privacy" = "Fortrolighedspolitik"; + +"getstarted.buttons.buyaccount" = "Køb konto"; + +"gdpr.collect.data.title" = "Personlige oplysninger, vi indsamler"; +"gdpr.collect.data.description" = "E-mailadresse med henblik på kontohåndtering og beskyttelse mod misbrug."; +"gdpr.usage.data.title" = "Anvendelse af personlige oplysninger indsamlet af os"; +"gdpr.usage.data.description" = "E-mailadresse bruges kun til at sende abonnementsoplysninger, betalingsbekræftelser, kundekorrespondance og salgsfremmende tilbud fra Private Internet Access."; +"gdpr.accept.button.title" = "Accepter og fortsæt"; + +"update.account.email.error" = "Lykkedes ikke at ændre konto-e-mail"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings new file mode 100644 index 000000000..ba5d2b2b5 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Registrierung bestätigen"; +"in_progress.message" = "Wir bestätigen deinen Kauf in unserem System. Es kann einen Moment dauern, also gedulde dich bitte etwas."; +"in_progress.redeem.message" = "Wir überprüfen derzeit Ihre Karten-PIN in unserem System. Dies kann einen Moment dauern. Bitte haben Sie etwas Geduld."; + +"success.title" = "Kauf abgeschlossen"; +"success.message_format" = "Vielen Dank für deine Registrierung. Wir haben dir deinen Benutzernamen und dein Passwort an deine E-Mail-Adresse unter %@ gesendet."; +"success.redeem.title" = "Karte erfolgreich eingelöst!"; +"success.redeem.message" = "Sie werden in Kürze eine E-Mail mit Ihrem Benutzernamen und Passwort erhalten.\n\nIhre Zugangsdaten"; +"success.username.caption" = "Benutzername"; +"success.password.caption" = "Passwort"; +"success.submit" = "Erste Schritte"; + +"failure.vc_title" = "Registrierung fehlgeschlagen"; +"failure.title" = "Konto nicht erstellt"; +"failure.message" = "Zur Zeit können wir kein Konto erstellen. Bitte später erneut versuchen.\n\nBeim erneuten Öffnen der App wird wieder versucht, ein Konto zu erstellen."; +"failure.purchase.sandbox.message" = "Das ausgewählte Sandbox-Abonnement ist in der Produktion nicht verfügbar."; +"failure.redeem.invalid.title" = "Ungültige Karten-PIN"; +"failure.redeem.invalid.message" = "Anscheinend haben Sie eine ungültige PIN eingegeben. Bitte erneut versuchen."; +"failure.redeem.claimed.title" = "Karte bereits eingelöst"; +"failure.redeem.claimed.message" = "Anscheinend wurde diese Karte bereits über ein anderes Konto eingelöst. Geben Sie eine andere PIN ein."; +"failure.submit" = "ZURÜCK"; + +"unreachable.vc_title" = "Fehler"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Keine Internetverbindung gefunden. Bitte deine Internetverbindung überprüfen und erneut versuchen.\n\nDu kannst die App später erneut aufrufen, um den Vorgang abzuschließen."; +"unreachable.submit" = "WIEDERHOLEN"; + +"purchase.uncredited.alert.message" = "Sie haben Transaktionen, die noch nicht gutgeschrieben wurden. Möchten Sie Ihre Kontodaten wiederherstellen?"; +"purchase.uncredited.alert.button.cancel" = "Abbrechen"; +"purchase.uncredited.alert.button.recover" = "Konto wiederherstellen"; + +"purchase.trials.intro" = "Jetzt 7 Tage gratis testen"; +"purchase.trials.price.after" = "Dann %@"; +"purchase.trials.money.back" = "30-Tage-Geld-zurück-Garantie"; +"purchase.trials.1year.protection" = "1 Jahr Daten- und Identitätsschutz"; +"purchase.trials.anonymous" = "Anonym surfen und Ihre IP-Adresse verbergen"; +"purchase.trials.devices" = "Unterstützung für 10 Geräte"; +"purchase.trials.devices.description" = "Schützen Sie sich auf bis zu 10 Geräten gleichzeitig."; +"purchase.trials.region" = "Einfache Verbindung zu jeder Region"; +"purchase.trials.servers" = "Mehr als 3300 Server in 32 Ländern"; +"purchase.trials.start" = "Abonnement beginnen"; +"purchase.trials.all.plans" = "Alle verfügbaren Pläne anzeigen"; + +"purchase.subscribe.now" = "Jetzt abonnieren"; + +// WALKTHROUGH + +"walkthrough.action.next" = "WEITER"; +"walkthrough.action.done" = "FERTIG"; +"walkthrough.action.skip" = "ÜBERSPRINGEN"; + +"walkthrough.page.1.title" = "Unterstützung für 10 Geräte"; +"walkthrough.page.1.description" = "Schützen Sie sich auf bis zu 10 Geräten gleichzeitig."; +"walkthrough.page.2.title" = "Bequem mit jeder beliebigen Region verbinden"; +"walkthrough.page.2.description" = "Mit Servern auf der ganzen Welt bist du immer geschützt."; +"walkthrough.page.3.title" = "Schütze dich vor Werbung"; +"walkthrough.page.3.description" = "Mit der Aktivierung unseres Inhalts-Blockers sehen Sie keine Anzeigen in Safari mehr."; + +"share.data.buttons.accept" = "Akzeptieren"; +"share.data.buttons.noThanks" = "Nein danke"; +"share.data.buttons.readMore" = "Mehr erfahren"; +"share.data.text.title" = "Bitte helfen Sie uns, unseren Service zu verbessern"; +"share.data.text.description" = "Um uns zu helfen, die Verbindungsleistung unseres Dienstes sicherzustellen, können Sie Ihre Verbindungsstatistiken anonym mit uns teilen. Diese Berichte enthalten keine persönlich identifizierbaren Informationen."; +"share.data.text.footer" = "Sie können dies jederzeit über Ihre Einstellungen steuern"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/UI.strings new file mode 100644 index 000000000..4268a80ca --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Schließen"; +"global.ok" = "OK"; +"global.cancel" = "Abbrechen"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings new file mode 100644 index 000000000..ed13eb4ab --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "An deinem Konto anmelden"; +"login.username.placeholder" = "Benutzername (p1234567)"; +"login.password.placeholder" = "Passwort"; +"login.submit" = "ANMELDEN"; +"login.restore.button" = "Keine Kontodaten erhalten?"; +"login.error.title" = "Anmelden"; +"login.error.validation" = "Du musst einen Benutzernamen und ein Passwort angeben."; +"login.error.unauthorized" = "Dein Benutzername oder Passwort ist falsch."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Anmeldung mit Kaufbeleg"; +"login.magic.link.title" = "Anmeldung mit magischem E-Mail-Link"; +"login.magic.link.response" = "Bitte überprüfen Sie Ihre E-Mail auf einen Login-Link."; +"login.magic.link.send" = "Link senden"; +"login.magic.link.invalid.email" = "Ungültige E-Mail-Adresse. Bitte erneut versuchen."; + +"purchase.title" = "VPN-Tarif auswählen"; +"purchase.subtitle" = "30-Tage-Geld-zurück-Garantie"; +"purchase.email.placeholder" = "E-Mail-Adresse"; +"purchase.continue" = "Weiter"; +"purchase.login.footer" = "Bereits ein Konto?"; +"purchase.login.button" = "Anmelden"; +"purchase.error.title" = "Kaufen"; +"purchase.error.validation" = "Sie müssen eine E-Mail-Adresse angeben."; +"purchase.error.connectivity.title" = "Verbindungsfehler"; +"purchase.error.connectivity.description" = "Wir können Private Internet Access nicht erreichen. Dies kann auf eine schlechte Internetverbindung zurückzuführen sein oder unser Service ist in deinem Land blockiert."; +"purchase.confirm.form.email" = "E-Mail-Adresse eingeben"; +"purchase.confirm.plan" = "Sie erwerben den %@-Tarif."; +"purchase.email.why" = "Wir benötigen Ihre E-Mail, um Ihren Benutzernamen und Ihr Passwort zu senden."; +"purchase.submit" = "Senden"; +"purchase.or" = "oder"; + +"upgrade.header" = "Willkommen zurück!"; +"upgrade.title" = "Sie müssen Ihr Abonnement erneuern, um Private Internet Access nutzen zu können."; +"upgrade.renew.now" = "Jetzt erneuern"; + + + +"redeem.title" = "Geschenkkarte einlösen"; +"redeem.subtitle" = "Geben Sie unten Ihre E-Mail-Adresse und die %lu-stellige PIN von Ihrer Geschenk- oder Testkarte ein."; +"redeem.email.placeholder" = "E-Mail-Adresse"; +"redeem.submit" = "SENDEN"; +"redeem.error.title" = "Einlösen"; +"redeem.error.code" = "Der Code muss aus %lu Ziffern bestehen."; +"redeem.error.allfields" = "Bitte geben Sie Ihre E-Mail-Adresse und Karten-PIN ein."; +"redeem.accessibility.back" = "Zurück"; +"redeem.giftcard.placeholder" = "PIN der Geschenkkarte"; + +"plan.monthly.title" = "Monatlich"; +"plan.yearly.title" = "Jährlich"; +"plan.yearly.detail_format" = "%@%@ pro Jahr"; +"plan.price_format" = "%@/Monat"; +"plan.best_value" = "Bestpreis"; +"plan.accessibility.per_month" = "pro Monat"; + +"restore.title" = "Nicht gutgeschriebenen Kauf wiederherstellen"; +"restore.subtitle" = "Wenn Sie einen Tarif über diese App erworben haben und Ihre Zugangsdaten nicht erhalten haben, können Sie sie hier erneut anfordern. Sie müssen dann nicht erneut bezahlen."; +"restore.email.placeholder" = "E-Mail-Adresse"; +"restore.submit" = "BESTÄTIGEN"; + +"iap.error.message.unavailable" = "Die Apple-Server sind momentan nicht verfügbar. Bitte später erneut versuchen."; +"iap.error.title" = "Fehler"; + +"agreement.trials.title" = "Nutzungsbedingungen für kostenlose Testversionen"; +"agreement.trials.message" = "Die Zahlung wird Ihrem Apple ID-Konto bei der Kaufbestätigung belastet. Das Abonnement verlängert sich automatisch, wenn es nicht mindestens 24 Stunden vor Ablauf der aktuellen Periode gekündigt wird. Die Verlängerung wird Ihrem Konto innerhalb von 24 Stunden vor Ablauf der aktuellen Periode in Rechnung gestellt. Sie können Ihre Abonnements verwalten und kündigen, indem Sie nach dem Kauf zu Ihren Kontoeinstellungen im App Store aufrufen.\n\nBestimmte kostenpflichtige Abonnements können eine kostenlose Testversion anbieten, bevor Sie Ihre Zahlungsmethode berechnen. Wenn Sie sich entscheiden, sich von einem kostenpflichtigen Abonnement abzumelden, bevor wir mit der Berechnung Ihrer Zahlungsmethode beginnen, kündigen Sie das Abonnement mindestens 24 Stunden vor Ablauf der kostenlosen Probezeit.\n\nKostenlose Testversionen sind nur für neue Benutzer verfügbar und liegen in unserem alleinigen Ermessen, und wenn Sie versuchen, sich für eine zusätzliche kostenlose Testversion anzumelden, wird Ihnen sofort die Standard-Abonnementgebühr in Rechnung gestellt.\n\nWir behalten uns das Recht vor, Ihre kostenlose Testversion jederzeit zu widerrufen.\n\nJeder ungenutzte Teil Ihrer kostenlosen Probezeit verfällt mit dem Kauf eines Abonnements.\n\nMit der Registrierung akzeptieren Sie diese Nutzungsbedingungen."; +"agreement.message" = "Nach der 7-tägigen kostenlosen Testperiode verlängert sich dieses Abonnement automatisch für %@, sofern es nicht mindestens 24 Stunden vor Ablauf der Testperiode gekündigt wird. Ihr Apple-ID-Konto wird für die Verlängerung innerhalb von 24 Stunden vor Ablauf des Testzeitraums belastet. Sie können Ihre Abonnements nach dem Kauf in den Einstellungen Ihres App Store-Kontos verwalten und kündigen. Jeder Benutzer kann die 7-tägige kostenlose Testperiode nur einmal in Anspruch nehmen. Jeder nicht genutzte Teil einer kostenlosen Testperiode, falls angeboten, verfällt beim Kauf eines Abonnements durch den Benutzer. Alle Preise enthalten die örtlich geltenden Verkaufssteuern.\n\nMit der Anmeldung akzeptieren Sie die $1 und $2."; +"agreement.trials.yearly.plan" = "Jahr"; +"agreement.trials.monthly.plan" = "Monat"; + +"agreement.message.tos" = "Nutzungsbedingungen"; +"agreement.message.privacy" = "Datenschutzrichtlinien"; + +"getstarted.buttons.buyaccount" = "Konto kaufen"; + +"gdpr.collect.data.title" = "Art der personenbezogenen Daten, die wir erfassen"; +"gdpr.collect.data.description" = "E-Mail-Adresse zum Zwecke der Kontoverwaltung und zum Schutz vor Missbrauch."; +"gdpr.usage.data.title" = "Verwendungszwecke für personenbezogene Daten, die von uns erfasst wurden"; +"gdpr.usage.data.description" = "Die E-Mail-Adresse wird lediglich zum Senden von Abonnementinformationen, Zahlungsbestätigungen, Kundenkorrespondenz und Sonderangeboten zu Private Internet Access verwendet."; +"gdpr.accept.button.title" = "Zustimmen und fortfahren"; + +"update.account.email.error" = "Konto-E-Mail nicht geändert"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings new file mode 100644 index 000000000..dacff3d57 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirm sign-up"; +"in_progress.message" = "We're confirming your purchase with our system. It could take a moment so hang in there."; +"in_progress.redeem.message" = "We're confirming your card PIN with our system. It could take a moment so hang in there."; + +"success.title" = "Purchase complete"; +"success.message_format" = "Thank you for signing up with us. We have sent your account username and password at your email address at %@"; +"success.redeem.title" = "Card redeemed successfully"; +"success.redeem.message" = "You will receive an email shortly with your username and password.\n\nYour login details"; +"success.username.caption" = "Username"; +"success.password.caption" = "Password"; +"success.submit" = "GET STARTED"; + +"failure.vc_title" = "Sign-up failed"; +"failure.title" = "Account creation failed"; +"failure.message" = "We're unable to create an account at this time. Please try again later. Reopening the app will re-attempt to create an account."; +"failure.purchase.sandbox.message" = "The selected sandbox subscription is not available in production."; +"failure.redeem.invalid.title" = "Invalid card PIN"; +"failure.redeem.invalid.message" = "Looks like you entered an invalid card PIN. Please try again."; +"failure.redeem.claimed.title" = "Card claimed already"; +"failure.redeem.claimed.message" = "Looks like this card has already been claimed by another account. You can try entering a different PIN."; +"failure.submit" = "GO BACK"; + +"unreachable.vc_title" = "Error"; +"unreachable.title" = "Whoops!"; +"unreachable.message" = "No internet connection found. Please confirm that you have an internet connection and hit retry below.\n\nYou can come back to the app later to finish the process."; +"unreachable.submit" = "TRY AGAIN"; + +"purchase.uncredited.alert.message" = "You have uncredited transactions. Do you want to recover your account details?"; +"purchase.uncredited.alert.button.cancel" = "Cancel"; +"purchase.uncredited.alert.button.recover" = "Recover account"; + +"purchase.trials.intro" = "Start your 7-day free trial"; +"purchase.trials.price.after" = "Then %@"; +"purchase.trials.money.back" = "30 day money back guarantee"; +"purchase.trials.1year.protection" = "1 year of privacy and identity protection"; +"purchase.trials.anonymous" = "Browse anonymously and hide your ip."; +"purchase.trials.devices" = "Support 10 devices at once"; +"purchase.trials.devices.description" = "Protect yourself on up to 10 devices at a time."; +"purchase.trials.region" = "Connect to any region easily"; +"purchase.trials.servers" = "More than 3300 servers in 32 countries"; +"purchase.trials.start" = "Start subscription"; +"purchase.trials.all.plans" = "See all available plans"; + +"purchase.subscribe.now" = "Subscribe now"; + +// WALKTHROUGH + +"walkthrough.action.next" = "NEXT"; +"walkthrough.action.done" = "DONE"; +"walkthrough.action.skip" = "SKIP"; + +"walkthrough.page.1.title" = "Support 10 devices at once"; +"walkthrough.page.1.description" = "Protect yourself on up to 10 devices at a time."; +"walkthrough.page.2.title" = "Connect to any region easily"; +"walkthrough.page.2.description" = "With servers around the globe, you are always under protection."; +"walkthrough.page.3.title" = "Protect yourself from ads"; +"walkthrough.page.3.description" = "Enabling our Content Blocker prevents ads from showing in Safari."; + +"share.data.buttons.accept" = "Accept"; +"share.data.buttons.noThanks" = "No, thanks"; +"share.data.buttons.readMore" = "Read more"; +"share.data.text.title" = "Please help us improve our service"; +"share.data.text.description" = "To help us ensure our service's connection performance, you can anonymously share your connection stats with us. These reports do not include any personally identifiable information."; +"share.data.text.footer" = "You can always control this from your settings"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/UI.strings new file mode 100644 index 000000000..98ec3d5e2 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Close"; +"global.ok" = "OK"; +"global.cancel" = "Cancel"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings new file mode 100644 index 000000000..91c5c4c53 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Sign in to your account"; +"login.username.placeholder" = "Username (p1234567)"; +"login.password.placeholder" = "Password"; +"login.submit" = "LOGIN"; +"login.restore.button" = "Didn't receive account details?"; +"login.error.title" = "Log in"; +"login.error.validation" = "You must enter a username and password."; +"login.error.unauthorized" = "Your username or password is incorrect."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Login using purchase receipt"; +"login.magic.link.title" = "Login using magic email link"; +"login.magic.link.response" = "Please check your e-mail for a login link."; +"login.magic.link.send" = "Send Link"; +"login.magic.link.invalid.email" = "Invalid email. Please try again."; + +"purchase.title" = "Select a VPN plan"; +"purchase.subtitle" = "30-day money back guarantee"; +"purchase.email.placeholder" = "Email address"; +"purchase.continue" = "Continue"; +"purchase.login.footer" = "Already have an account?"; +"purchase.login.button" = "Sign in"; +"purchase.error.title" = "Purchase"; +"purchase.error.validation" = "You must enter an email address."; +"purchase.error.connectivity.title" = "Connection Failure"; +"purchase.error.connectivity.description" = "We are unable to reach Private Internet Access. This may due to poor internet or our service is blocked in your country."; +"purchase.confirm.form.email" = "Enter your email address"; +"purchase.confirm.plan" = "You are purchasing the %@ plan"; +"purchase.email.why" = "We need your email to send your username and password."; +"purchase.submit" = "Submit"; +"purchase.or" = "or"; + +"upgrade.header" = "Welcome Back!"; +"upgrade.title" = "In order to use Private Internet Access, you’ll need to renew your subscription."; +"upgrade.renew.now" = "Renew now"; + + + +"redeem.title" = "Redeem gift card"; +"redeem.subtitle" = "Type in your email address and the %lu digit PIN from your gift card or trial card below."; +"redeem.email.placeholder" = "Email address"; +"redeem.submit" = "SUBMIT"; +"redeem.error.title" = "Redeem"; +"redeem.error.code" = "Code must be %lu numeric digits."; +"redeem.error.allfields"="Please type in your email and card PIN."; +"redeem.accessibility.back" = "Back"; +"redeem.giftcard.placeholder" = "Gift card PIN"; + +"plan.monthly.title" = "Monthly"; +"plan.yearly.title" = "Yearly"; +"plan.yearly.detail_format" = "%@%@ per year"; +"plan.price_format" = "%@/mo"; +"plan.best_value" = "Best value"; +"plan.accessibility.per_month" = "per month"; + +"restore.title" = "Restore uncredited purchase"; +"restore.subtitle" = "If you purchased a plan through this app and didn't receive your credentials, you can send them again from here. You will not be charged during this process."; +"restore.email.placeholder" = "Email address"; +"restore.submit" = "CONFIRM"; + +"iap.error.message.unavailable" = "Apple servers currently unavailable. Please try again later."; +"iap.error.title" = "Error"; + +"agreement.trials.title" = "Free trials terms and conditions"; +"agreement.trials.message" = "Payment will be charged to your Apple ID account at the confirmation of purchase. Subscription automatically renews unless it is canceled at least 24 hours before the end of the current period. Your account will be charged for renewal within 24 hours prior to the end of the current period. You can manage and cancel your subscriptions by going to your account settings on the App Store after purchase.\n\nCertain Paid Subscriptions may offer a free trial prior to charging your payment method. If you decide to unsubscribe from a Paid Subscription before we start charging your payment method, cancel the subscription at least 24 hours before the free trial ends.\n\nFree trials are only available to new users, and are at our sole discretion, and if you attempt to sign up for an additional free trial, you will be immediately charged with the standard Subscription Fee.\n\nWe reserve the right to revoke your free trial at any time.\n\nAny unused portion of your free trial period will be forfeited upon purchase of a subscription.\n\nSigning up constitutes acceptance of this terms and conditions."; +"agreement.message" = "After the 7 days free trial this subscription automatically renews for %@ unless it is canceled at least 24 hours before the end of the trial period. Your Apple ID account will be charged for renewal within 24 hours before the end of the trial period. You can manage and cancel your subscriptions by going to your App Store account settings after purchase. 7-days trial offer is limited to one 7-days trial offer per user. Any unused portion of a free trial period, if offered, will be forfeited when the user purchases a subscription. All prices include applicable local sales taxes.\n\nSigning up constitutes acceptance of the $1 and the $2."; +"agreement.trials.yearly.plan" = "year"; +"agreement.trials.monthly.plan" = "month"; + +"agreement.message.tos" = "Terms of Service"; +"agreement.message.privacy" = "Privacy Policy"; + +"getstarted.buttons.buyaccount" = "Buy account"; + +"gdpr.collect.data.title" = "Personal information we collect"; +"gdpr.collect.data.description" = "E-mail Address for the purposes of account management and protection from abuse."; +"gdpr.usage.data.title" = "Uses of personal information collected by us"; +"gdpr.usage.data.description" = "E-mail address is used to send subscription information, payment confirmations, customer correspondence, and Private Internet Access promotional offers only."; +"gdpr.accept.button.title" = "Agree and continue"; + +"update.account.email.error" = "Failed to modify account email"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings new file mode 100644 index 000000000..3ebdb9fd3 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirmar registro"; +"in_progress.message" = "Estamos confirmando la compra en el sistema. Podrías tardar unos instantes, así que espera."; +"in_progress.redeem.message" = "Estamos confirmando el PIN de tu tarjeta en nuestro sistema. Puede tardar un momento, así que espera un poco."; + +"success.title" = "Compra completa"; +"success.message_format" = "Gracias por registrarte con nosotros. Te enviamos el nombre de usuario y contraseña de tu cuenta a tu dirección de email en %@"; +"success.redeem.title" = "Tarjeta canjeada correctamente"; +"success.redeem.message" = "Recibirás un mensaje de correo electrónico dentro de poco con tu nombre de usuario y contraseña.\n\nTu información de inicio de sesión"; +"success.username.caption" = "Nombre de usuario"; +"success.password.caption" = "Contraseña "; +"success.submit" = "Empieza"; + +"failure.vc_title" = "Falló el registro"; +"failure.title" = "Falló la creación de la cuenta"; +"failure.message" = "No pudimos crear una cuenta en este momento. Por favor, inténtalo de nuevo más tarde. \nSi vuelves a abrir la aplicación intentaremos crear una cuenta otra vez."; +"failure.purchase.sandbox.message" = "La suscripción del entorno aislado seleccionado no está disponible en la producción."; +"failure.redeem.invalid.title" = "El PIN de la tarjeta no es válido"; +"failure.redeem.invalid.message" = "Parece que ingresaste un PIN de tarjeta inválido. Por favor, inténtalo de nuevo."; +"failure.redeem.claimed.title" = "La tarjeta ya fue reclamada"; +"failure.redeem.claimed.message" = "Parece que esta tarjeta ha sido reclamada por otra cuenta. Puedes intentar ingresar un PIN diferente."; +"failure.submit" = "ATRÁS"; + +"unreachable.vc_title" = "Error"; +"unreachable.title" = "¡Ups!"; +"unreachable.message" = "No se encontró conexión a Internet. Por favor, confirma que tienes una conexión a Internet y toca en intentar de nuevo más abajo.\n\nPuedes regresar después a la aplicación para terminar el proceso."; +"unreachable.submit" = "VOLVER A INTENTAR"; + +"purchase.uncredited.alert.message" = "Tienes transacciones sin acreditar. ¿Seguro que quieres recuperar los detalles de tu cuenta?"; +"purchase.uncredited.alert.button.cancel" = "Cancelar"; +"purchase.uncredited.alert.button.recover" = "Recuperar cuenta"; + +"purchase.trials.intro" = "Inicia tu prueba gratuita de 7 días"; +"purchase.trials.price.after" = "Después, %@"; +"purchase.trials.money.back" = "Garantía de devolución de 30 días"; +"purchase.trials.1year.protection" = "1 año de privacidad y protección de la identidad."; +"purchase.trials.anonymous" = "Navega de forma anónima y oculta tu IP."; +"purchase.trials.devices" = "Admite 10 dispositivos a la vez."; +"purchase.trials.devices.description" = "Protégete en hasta 10 dispositivos a la vez."; +"purchase.trials.region" = "Conéctate a cualquier región con facilidad."; +"purchase.trials.servers" = "Más de 3300 servidores en 32 países."; +"purchase.trials.start" = "Iniciar suscripción"; +"purchase.trials.all.plans" = "Ver todos los planes disponibles."; + +"purchase.subscribe.now" = "Suscríbete ahora"; + +// WALKTHROUGH + +"walkthrough.action.next" = "SIGUIENTE"; +"walkthrough.action.done" = "TERMINADO"; +"walkthrough.action.skip" = "OMITIR"; + +"walkthrough.page.1.title" = "Admite 10 dispositivos a la vez"; +"walkthrough.page.1.description" = "Protégete en hasta 10 dispositivos a la vez."; +"walkthrough.page.2.title" = "Conéctate a cualquier región con facilidad"; +"walkthrough.page.2.description" = "Con servidores en todo el mundo, siempre estarás protegido."; +"walkthrough.page.3.title" = "Protégete de la publicidad"; +"walkthrough.page.3.description" = "Habilita nuestro Bloqueador de contenido para impedir que aparezca publicidad en Safari."; + +"share.data.buttons.accept" = "Aceptar"; +"share.data.buttons.noThanks" = "No, gracias"; +"share.data.buttons.readMore" = "Más información"; +"share.data.text.title" = "Ayúdanos a mejorar nuestro servicio."; +"share.data.text.description" = "Para ayudarnos a garantizar el rendimiento de la conexión de nuestro servicio, puedes compartir con nosotros tus estadísticas de conexión de forma anónima. Estos informes no contienen ninguna información personal identificable."; +"share.data.text.footer" = "Siempre puedes controlarlo desde tus ajustes."; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings new file mode 100644 index 000000000..e645f72b5 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versión %@ (%@)"; +"global.close" = "Cerrar"; +"global.ok" = "Aceptar"; +"global.cancel" = "Cancelar"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings new file mode 100644 index 000000000..3c47f73e3 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Inicia sesión en tu cuenta"; +"login.username.placeholder" = "Nombre de usuario (p1234567)"; +"login.password.placeholder" = "Contraseña "; +"login.submit" = "INICIAR SESIÓN"; +"login.restore.button" = "¿No has recibido los detalles de la cuenta?"; +"login.error.title" = "Iniciar sesión"; +"login.error.validation" = "Debe ingresar un nombre de usuario y una contraseña."; +"login.error.unauthorized" = "Tu nombre de usuario o contraseña son incorrectos."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Inicia sesión con el recibo de compra"; +"login.magic.link.title" = "Inicia sesión con el vínculo mágico del correo electrónico."; +"login.magic.link.response" = "Busca en tu correo electrónico un enlace de inicio de sesión."; +"login.magic.link.send" = "Enviar enlace"; +"login.magic.link.invalid.email" = "Correo electrónico no válido. Vuelve a intentarlo."; + +"purchase.title" = "Selecciona un plan VPN"; +"purchase.subtitle" = "Garantía de devolución de 30 días"; +"purchase.email.placeholder" = "Dirección de correo electrónico"; +"purchase.continue" = "Continuar"; +"purchase.login.footer" = "¿Ya tienes una cuenta?"; +"purchase.login.button" = "Inicia sesión"; +"purchase.error.title" = "Comprar"; +"purchase.error.validation" = "Debes ingresar una dirección de email."; +"purchase.error.connectivity.title" = "Falla en la conexión"; +"purchase.error.connectivity.description" = "No pudimos localizar a Private Internet Access. Esto puede ser debido a una mala conexión con Internet o a que nuestro servicio está bloqueado en su país."; +"purchase.confirm.form.email" = "Introduce tu dirección de correo electrónico"; +"purchase.confirm.plan" = "Estás comprando el plan %@."; +"purchase.email.why" = "Necesitamos tu dirección de correo electrónico para enviar tu nombre de usuario y tu contraseña."; +"purchase.submit" = "Enviar"; +"purchase.or" = "o"; + +"upgrade.header" = "¡Hola otra vez!"; +"upgrade.title" = "Para usar Private Internet Access debes renovar tu suscripción."; +"upgrade.renew.now" = "Renovar ahora"; + + + +"redeem.title" = "Canjear tarjeta de regalo"; +"redeem.subtitle" = "Escribe abajo tu dirección de correo electrónico y el PIN de %lu dígitos de tu tarjeta de regalo o tarjeta de prueba."; +"redeem.email.placeholder" = "Dirección de correo electrónico"; +"redeem.submit" = "ENVIAR"; +"redeem.error.title" = "Canjear"; +"redeem.error.code" = "El código debe tener %lu dígitos numéricos."; +"redeem.error.allfields" = "Escribe tu dirección de correo electrónico y el PIN de tu tarjeta."; +"redeem.accessibility.back" = "Volver"; +"redeem.giftcard.placeholder" = "PIN de tarjeta regalo"; + +"plan.monthly.title" = "Mensual"; +"plan.yearly.title" = "Anual"; +"plan.yearly.detail_format" = "%@%@ al año"; +"plan.price_format" = "%@/m"; +"plan.best_value" = "Mejor oferta"; +"plan.accessibility.per_month" = "por mes"; + +"restore.title" = "Restablecer compra no acreditada"; +"restore.subtitle" = "Si compraste un plan a través de esta aplicación y no recibes tus credenciales, puedes reiniciar la renovación desde aquí. No se realizarán cargos durante este proceso. \n"; +"restore.email.placeholder" = "Correo electrónico"; +"restore.submit" = "CONFIRMAR"; + +"iap.error.message.unavailable" = "Actualmente, los servidores de Apple no están disponibles. Por favor, inténtalo de nuevo más tarde."; +"iap.error.title" = "Error"; + +"agreement.trials.title" = "Términos y condiciones de la prueba gratuita."; +"agreement.trials.message" = "Se realizará un cobro en tu cuenta de Apple ID en el momento de confirmar la compra. Las suscripciones se renuevan automáticamente a menos que se cancelen como mínimo 24 horas antes de la finalización del periodo actual. Se cobrará la cantidad de la renovación en un plazo de 24 horas antes de la finalización del período actual. Tu mismo podrás gestionar y cancelar las suscripciones en los ajustes de App Store después de la compra. \n\nAlgunas suscripciones de pago pueden ofrecer una prueba gratuita antes de realizar cobros según tu método de pago. Si decides darte de baja de una suscripción de pago antes de que comencemos a cobrar tu método de pago, cancela la suscripción al menos 24 horas antes de que finalice la prueba gratuita.\n\nLas pruebas gratuitas solo están disponibles para nuevos usuarios y quedan a nuestra entera discreción. Si intentas registrarte para obtener una prueba gratuita adicional, se te cobrará de inmediato la tarifa de suscripción estándar.\n\nNos reservamos el derecho de revocar tu prueba gratuita en cualquier momento.\n\nLas secciones sin usar del periodo de prueba gratuito se perderán si el usuario compra una suscripción.\n\nSi te registras, aceptas estos términos y condiciones."; +"agreement.message" = "Después de los 7 días de prueba gratuita, esta suscripción se renueva automáticamente por %@ a menos que se cancele al menos 24 horas antes del final del período de prueba. Se cobrará la renovación en tu cuenta de ID de Apple en un plazo de 24 horas antes de que finalice el periodo de prueba. Puedes gestionar y cancelar tus suscripciones accediendo a los ajustes de tu cuenta de App Store después de la compra. La oferta de prueba de 7 días se limita a una oferta de prueba de 7 días por usuario. Cualquier parte no utilizada de un período de prueba gratuito, si se ofrece, se perderá cuando el usuario compre una suscripción. Todos los precios incluyen los impuestos de venta locales aplicables.\n\nSi te registras, aceptas los $1 y la $2."; +"agreement.trials.yearly.plan" = "año"; +"agreement.trials.monthly.plan" = "mes"; + +"agreement.message.tos" = "Términos de servicio"; +"agreement.message.privacy" = "Política de privacidad"; + +"getstarted.buttons.buyaccount" = "Comprar cuenta"; + +"gdpr.collect.data.title" = "Información personal que recopilamos"; +"gdpr.collect.data.description" = "Dirección de correo electrónico con fines de gestión de cuenta y protección frente a abusos."; +"gdpr.usage.data.title" = "Usos de la información personal que recopilamos"; +"gdpr.usage.data.description" = "La dirección de correo electrónico solo se usa para enviar información de suscripción, confirmaciones de pago, correspondencia al cliente y ofertas promocionales de Private Internet Access."; +"gdpr.accept.button.title" = "Aceptar y continuar"; + +"update.account.email.error" = "Error al modificar el correo electrónico de la cuenta"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings new file mode 100644 index 000000000..a99c30197 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirmation d'inscription"; +"in_progress.message" = "Notre système est en train de confirmer votre achat. Cela pourrait prendre un moment, nous vous prions donc de patienter."; +"in_progress.redeem.message" = "Notre système est en train de confirmer le code PIN de votre carte. Cela pourrait prendre un moment, nous vous prions donc de patienter."; + +"success.title" = "Achat terminé"; +"success.message_format" = "Merci pour votre inscription. L'identifiant et le mot de passe de votre compte ont été envoyés à votre adresse e-mail %@"; +"success.redeem.title" = "Carte échangée avec succès"; +"success.redeem.message" = "Vous allez bientôt recevoir un e-mail contenant votre nom d'utilisateur et votre mot de passe.\n\nDétails de vos identifiants"; +"success.username.caption" = "Nom d'utilisateur"; +"success.password.caption" = "Mot de passe"; +"success.submit" = "Commencer"; + +"failure.vc_title" = "Échec de la connexion"; +"failure.title" = "La création du compte a échoué"; +"failure.message" = "Nous ne parvenons pas à créer un compte pour l'instant. Veuillez réessayer plus tard. \n\nRouvrir l'application engendrera une nouvelle tentative de création de compte."; +"failure.purchase.sandbox.message" = "L'abonnement sandbox sélectionné n'est pas disponible en production."; +"failure.redeem.invalid.title" = "Code PIN de la carte invalide"; +"failure.redeem.invalid.message" = "Il semblerait que le code PIN de la carte saisie soit invalide. Veuillez réessayer."; +"failure.redeem.claimed.title" = "Carte déjà utilisée"; +"failure.redeem.claimed.message" = "Il semblerait que cette carte soit déjà utilisée sur un autre compte. Vous pouvez essayer de saisir un code PIN différent."; +"failure.submit" = "REVENIR"; + +"unreachable.vc_title" = "Erreur"; +"unreachable.title" = "Oups !"; +"unreachable.message" = "Aucune connexion Internet trouvée. Veuillez confirmer que vous disposez d'une connexion Internet et cliquez de nouveau sur « Réessayer » ci-dessous.\n\nVous pourrez revenir dans l'application plus tard pour terminer le processus."; +"unreachable.submit" = "RÉESSAYER"; + +"purchase.uncredited.alert.message" = "Vous avez des transaction non créditées. Voulez-vous restaurer les détails de votre compte ?"; +"purchase.uncredited.alert.button.cancel" = "Annuler"; +"purchase.uncredited.alert.button.recover" = "Restaurer le compte"; + +"purchase.trials.intro" = "Démarrez votre essai gratuit de 7 jours"; +"purchase.trials.price.after" = "Ensuite %@"; +"purchase.trials.money.back" = "Garantie satisfait ou remboursé sur 30 jours"; +"purchase.trials.1year.protection" = "1 an de confidentialité et de protection de l'identité"; +"purchase.trials.anonymous" = "Surfez anonymement et masquez votre IP."; +"purchase.trials.devices" = "Prise en charge de 10 appareils en même temps"; +"purchase.trials.devices.description" = "Protégez-vous sur jusqu'à 10 appareils en même temps."; +"purchase.trials.region" = "Connectez-vous facilement à n'importe quelle région"; +"purchase.trials.servers" = "Plus de 3300 serveurs dans 32 pays"; +"purchase.trials.start" = "Commencer l'abonnement"; +"purchase.trials.all.plans" = "Voir tous les forfaits disponibles"; + +"purchase.subscribe.now" = "S'abonner maintenant"; + +// WALKTHROUGH + +"walkthrough.action.next" = "SUIVANT"; +"walkthrough.action.done" = "TERMINÉ"; +"walkthrough.action.skip" = "PASSER"; + +"walkthrough.page.1.title" = "Prend en charge 10 appareils en même temps"; +"walkthrough.page.1.description" = "Protégez-vous sur jusqu'à 10 appareils à la fois."; +"walkthrough.page.2.title" = "Connectez-vous facilement à n'importe quelle région"; +"walkthrough.page.2.description" = "Avec des serveurs partout dans le monde, vous êtes toujours sous protection."; +"walkthrough.page.3.title" = "Protégez-vous contre les publicités"; +"walkthrough.page.3.description" = "Activer notre bloqueur de contenu empêche les publicités de s'afficher dans Safari."; + +"share.data.buttons.accept" = "Accepter"; +"share.data.buttons.noThanks" = "Non, merci"; +"share.data.buttons.readMore" = "Lire plus"; +"share.data.text.title" = "Merci de nous aider à améliorer notre service"; +"share.data.text.description" = "Pour nous aider à garantir les performances de connexion de notre service, vous pouvez partager vos statistiques de connexion de manière anonyme avec nous. Ces rapports ne contiennent aucune information personnellement identifiable."; +"share.data.text.footer" = "Vous pouvez toujours contrôler cela à partir de vos paramètres."; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings new file mode 100644 index 000000000..fffdf519f --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Fermer"; +"global.ok" = "OK"; +"global.cancel" = "Annuler"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings new file mode 100644 index 000000000..623c17c3a --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Connectez-vous à votre compte"; +"login.username.placeholder" = "Nom d'utilisateur (p1234567)"; +"login.password.placeholder" = "Mot de passe"; +"login.submit" = "CONNEXION"; +"login.restore.button" = "Vous n'avez pas reçu les détails de votre compte ?"; +"login.error.title" = "Connexion"; +"login.error.validation" = "Vous devez saisir un nom d'utilisateur et un mot de passe."; +"login.error.unauthorized" = "Votre nom d'utilisateur ou mot de passe est incorrect."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Connectez-vous à l'aide du reçu d'achat"; +"login.magic.link.title" = "Connectez-vous à l'aide du lien e-mail magique"; +"login.magic.link.response" = "Veuillez vérifier vos e-mails pour trouver un lien de connexion."; +"login.magic.link.send" = "Envoyer un lien"; +"login.magic.link.invalid.email" = "E-mail invalide. Veuillez réessayer."; + +"purchase.title" = "Sélectionnez un forfait VPN"; +"purchase.subtitle" = "Garantie satisfait ou remboursé sur 30 jours"; +"purchase.email.placeholder" = "Adresse e-mail"; +"purchase.continue" = "Continuer"; +"purchase.login.footer" = "Vous avez déjà un compte ?"; +"purchase.login.button" = "Connectez-vous"; +"purchase.error.title" = "Acheter"; +"purchase.error.validation" = "Vous devez entrer une adresse e-mail."; +"purchase.error.connectivity.title" = "Échec de la connexion"; +"purchase.error.connectivity.description" = "Nous n'arrivons pas à joindre Private Internet Access. Cela peut être dû à une connexion Internet de faible qualité ou parce que notre service est bloqué dans votre pays."; +"purchase.confirm.form.email" = "Saisissez votre adresse e-mail"; +"purchase.confirm.plan" = "Vous achetez le forfait %@"; +"purchase.email.why" = "Nous avons besoin de votre e-mail pour envoyer votre nom d'utilisateur et votre mot de passe."; +"purchase.submit" = "Envoyer"; +"purchase.or" = "ou"; + +"upgrade.header" = "Bienvenue !"; +"upgrade.title" = "Afin d'utiliser Private Internet Access, vous devrez renouveler votre abonnement."; +"upgrade.renew.now" = "Renouveler maintenant"; + + + +"redeem.title" = "Échanger carte cadeau"; +"redeem.subtitle" = "Veuillez saisir ci-dessous votre adresse e-mail et le code PIN à %lu chiffres de votre carte cadeau ou carte d'essai."; +"redeem.email.placeholder" = "Adresse e-mail"; +"redeem.submit" = "ENVOYER"; +"redeem.error.title" = "Échanger"; +"redeem.error.code" = "Le code doit contenir %lu chiffres numériques."; +"redeem.error.allfields" = "Saisissez votre e-mail et le code PIN de votre carte."; +"redeem.accessibility.back" = "Retour"; +"redeem.giftcard.placeholder" = "Code PIN de la carte"; + +"plan.monthly.title" = "Mensuellement"; +"plan.yearly.title" = "Annuellement"; +"plan.yearly.detail_format" = "%@%@ par an"; +"plan.price_format" = "%@/mois"; +"plan.best_value" = "Économique"; +"plan.accessibility.per_month" = "par mois"; + +"restore.title" = "Restaurer l'achat non crédité"; +"restore.subtitle" = "Si vous avez acheté un forfait via cette application et n'avez pas reçu vos identifiants, il est possible de les renvoyer à partir d'ici. Cette action ne vous sera pas facturée."; +"restore.email.placeholder" = "Adresse e-mail"; +"restore.submit" = "CONFIRMER"; + +"iap.error.message.unavailable" = "Les serveurs Apple ne sont pas disponibles actuellement. Veuillez réessayer plus tard."; +"iap.error.title" = "Erreur"; + +"agreement.trials.title" = "Termes et conditions des essais gratuits"; +"agreement.trials.message" = "Le paiement sera débité de votre compte Apple ID au moment de la confirmation de l'achat. L'abonnement se renouvelle automatiquement à moins qu'il ne soit annulé au moins 24 heures avant la fin de la période en cours. Votre compte sera débité du renouvellement dans les 24 heures précédant la fin de la période actuelle. Vous pouvez gérer et annuler vos abonnements en accédant aux paramètres du compte sur l'App Store après l'achat.\n\nCertains abonnements payants peuvent offrir un essai gratuit avant de débiter votre méthode de paiement. Si vous décidez de vous désabonner d'un abonnement payant avant que nous commencions à débiter votre méthode de paiement, annulez l'abonnement au moins 24 heures avant la fin de l'essai.\n\nLes essais gratuits ne sont disponibles que pour les nouveaux utilisateurs et sont à notre entière discrétion et si vous tentez de vous inscrire pour un autre essai gratuit, vous serez immédiatement débité des frais d'abonnement standards.\n\nNous nous réservons le droit de révoquer votre essai gratuit à tout moment.\n\nToute partie non utilisée de votre période d'essai gratuit sera abandonnée au moment de l'achat d'un abonnement.\n\nL'inscription constitue l'acceptation de ces termes et conditions."; +"agreement.message" = "Après l'essai gratuit de 7 jour, cet abonnement est renouvelé automatiquement pour %@, sauf s'il est annulé au moins 24 heures avant la fin de la période d'essai. Votre compte de l'identifiant Apple sera facturé pour le renouvellement 24 heures avant la fin de la période d'essai. Vous pouvez gérer et annuler vos abonnements en accédant aux paramètres de votre compte de l'App Store après l'achat. L'offre de l'essai de 7 jours est limité à une seule offre d'essai de 7 jours par utilisateur. Toute partie non utilisée d'une période d'essai (le cas échéant) sera abandonnée lorsque l'utilisateur achète une abonnement. Tous les prix comprennent les taxes locales applicables.\n\nL'abonnement signifie que vous acceptez les $1 et la $2."; +"agreement.trials.yearly.plan" = "an"; +"agreement.trials.monthly.plan" = "mois"; + +"agreement.message.tos" = "Conditions d'utilisation"; +"agreement.message.privacy" = "Politique de confidentialité"; + +"getstarted.buttons.buyaccount" = "Acheter un compte"; + +"gdpr.collect.data.title" = "Informations personnelles que nous collectons"; +"gdpr.collect.data.description" = "Adresse e-mail dans le but de gérer le compte et de protéger des abus."; +"gdpr.usage.data.title" = "Utilisation des informations personnelles que nous collectons"; +"gdpr.usage.data.description" = "L'adresse e-mail est utilisée pour envoyer les informations d'abonnement, les confirmation de paiement, la correspondance avec le client, et les offres promotionnelles de Private Internet Access uniquement."; +"gdpr.accept.button.title" = "Accepter et continuer"; + +"update.account.email.error" = "Échec de la modification de l'e-mail du compte"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings new file mode 100644 index 000000000..b60ca1b4e --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Conferma registrazione"; +"in_progress.message" = "Conferma dell'acquisto col sistema in corso. Potrebbe impiegare qualche secondo. Attendi."; +"in_progress.redeem.message" = "Conferma del PIN della tua carta col sistema in corso. Potrebbe impiegare qualche secondo. Attendi."; + +"success.title" = "Acquisto completato"; +"success.message_format" = "Grazie per la registrazione. Ti abbiamo inviato nome utente e password del tuo account all'indirizzo e-mail %@"; +"success.redeem.title" = "Carta riscossa"; +"success.redeem.message" = "Riceverai un'email a breve con nome utente e password.\n\nI tuoi dati d'accesso"; +"success.username.caption" = "Nome utente"; +"success.password.caption" = "Password"; +"success.submit" = "Inizia"; + +"failure.vc_title" = "Registrazione non riuscita"; +"failure.title" = "Errore di creazione account"; +"failure.message" = "Impossibile creare un account in questo momento. Riprova più tardi. \n\nRiaprendo l'app si riproverà a creare un account."; +"failure.purchase.sandbox.message" = "L'abbonamento del sandbox selezionato on è disponibile in produzione."; +"failure.redeem.invalid.title" = "PIN della carta non valido"; +"failure.redeem.invalid.message" = "Hai inserito un PIN della carta non valido. Riprova."; +"failure.redeem.claimed.title" = "Carta già riscattata"; +"failure.redeem.claimed.message" = "Questa carta è già stata riscattata da un altro account. Prova a inserire un PIN diverso."; +"failure.submit" = "INDIETRO"; + +"unreachable.vc_title" = "Errore"; +"unreachable.title" = "Ops!"; +"unreachable.message" = "Nessuna connessione Internet trovata. Verifica la connessione Internet e premi Riprova di seguito.\n\nPuoi tornare all'app più tardi per terminare il processo."; +"unreachable.submit" = "RIPROVA"; + +"purchase.uncredited.alert.message" = "Hai transazioni non accreditate. Vuoi recuperare i dati del tuo account?"; +"purchase.uncredited.alert.button.cancel" = "Annulla"; +"purchase.uncredited.alert.button.recover" = "Recupera account"; + +"purchase.trials.intro" = "Inizia la tua prova gratuita da 7 giorni"; +"purchase.trials.price.after" = "Poi a %@"; +"purchase.trials.money.back" = "Garanzia di rimborso entro 30 giorni"; +"purchase.trials.1year.protection" = "1 anno di privacy e protezione d'indentità"; +"purchase.trials.anonymous" = "Sfoglia anonimamente e nascondi il tuo IP."; +"purchase.trials.devices" = "Supporta 10 dispositivi alla volta"; +"purchase.trials.devices.description" = "Proteggi un massimo di 10 dispositivi alla volta."; +"purchase.trials.region" = "Connettiti facilmente a qualsiasi regione"; +"purchase.trials.servers" = "Oltre 3300 server in 32 Paesi"; +"purchase.trials.start" = "Inizia abbonamento"; +"purchase.trials.all.plans" = "Vedi tutti i piani disponibili"; + +"purchase.subscribe.now" = "Iscriviti ora"; + +// WALKTHROUGH + +"walkthrough.action.next" = "AVANTI"; +"walkthrough.action.done" = "FATTO"; +"walkthrough.action.skip" = "SALTA"; + +"walkthrough.page.1.title" = "Supporta 10 dispositivi alla volta"; +"walkthrough.page.1.description" = "Proteggi te stesso su un massimo di 10 dispositivi alla volta."; +"walkthrough.page.2.title" = "Connettiti facilmente a qualsiasi regione"; +"walkthrough.page.2.description" = "Con server in tutto il mondo, sei sempre protetto."; +"walkthrough.page.3.title" = "Proteggiti dalle pubblicità"; +"walkthrough.page.3.description" = "Abilitando il nostro Blocco dei contenuti non visualizzerai la pubblicità mentre navighi con Safari."; + +"share.data.buttons.accept" = "Accetta"; +"share.data.buttons.noThanks" = "No, grazie"; +"share.data.buttons.readMore" = "Leggi di più"; +"share.data.text.title" = "Aiutaci a migliorare il tuo servizio"; +"share.data.text.description" = "Per aiutarci a garantire le prestazioni di connessione del nostro servizio, puoi condividere in modo anonimo le tue statistiche di connessione con noi. Questi rapporti non contengono informazioni d'identificazione personale."; +"share.data.text.footer" = "Puoi sempre controllare questa funzione dalle tue impostazioni"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/UI.strings new file mode 100644 index 000000000..fc2c6c196 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versione %@ (%@)"; +"global.close" = "Chiudi"; +"global.ok" = "OK"; +"global.cancel" = "Annulla"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings new file mode 100644 index 000000000..197265683 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Accedi al tuo account"; +"login.username.placeholder" = "Nome utente (p1234567)"; +"login.password.placeholder" = "Password"; +"login.submit" = "ACCEDI"; +"login.restore.button" = "Non hai ancora ricevuto i dettagli dell'account?"; +"login.error.title" = "Accedi"; +"login.error.validation" = "Devi inserire un nome utente e una password."; +"login.error.unauthorized" = "Nome utente o password non valida"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Accedi mediante ricevuta d'acquisto"; +"login.magic.link.title" = "Accedi tramite il link magico della mail"; +"login.magic.link.response" = "Controlla la tua mail per ottenere il link d'accesso."; +"login.magic.link.send" = "Invia link"; +"login.magic.link.invalid.email" = "Indirizzo email non valido. Riprova."; + +"purchase.title" = "Seleziona un piano VPN"; +"purchase.subtitle" = "Garanzia di rimborso entro 30 giorni"; +"purchase.email.placeholder" = "Indirizzo email"; +"purchase.continue" = "Continua"; +"purchase.login.footer" = "Possiedi già un account?"; +"purchase.login.button" = "Accedi"; +"purchase.error.title" = "Acquista"; +"purchase.error.validation" = "Devi indicare un indirizzo e-mail."; +"purchase.error.connectivity.title" = "Errore di connessione"; +"purchase.error.connectivity.description" = "Non siamo in grado di stabilire l'accesso a una rete Internet privata. Ciò potrebbe essere dovuto a una scarsa qualità della rete o a un blocco dei nostri servizi nel tuo paese."; +"purchase.confirm.form.email" = "Inserisci il tuo indirizzo email"; +"purchase.confirm.plan" = "Stai acquistando il piano %@"; +"purchase.email.why" = "Per inviarti nome utente e password, abbiamo bisogno del tuo indirizzo email."; +"purchase.submit" = "Invia"; +"purchase.or" = "o"; + +"upgrade.header" = "Bentornato!"; +"upgrade.title" = "Per usare Private Internet Access, devi rinnovare l'abbonamento."; +"upgrade.renew.now" = "Rinnova adesso"; + + + +"redeem.title" = "Riscatta la carta regalo"; +"redeem.subtitle" = "Digita qui sotto il tuo indirizzo email e le %lu cifre del PIN della carta regalo o carta di prova."; +"redeem.email.placeholder" = "Indirizzo email"; +"redeem.submit" = "INVIA"; +"redeem.error.title" = "Riscatta"; +"redeem.error.code" = "Il codice dev'essere di %lu cifre."; +"redeem.error.allfields" = "Digita il tuo indirizzo email e PIN della carta."; +"redeem.accessibility.back" = "Indietro"; +"redeem.giftcard.placeholder" = "PIN carta regalo"; + +"plan.monthly.title" = "Mensile"; +"plan.yearly.title" = "Annuale"; +"plan.yearly.detail_format" = "%@%@ all'anno"; +"plan.price_format" = "%@ al mese"; +"plan.best_value" = "Valore migliore"; +"plan.accessibility.per_month" = "al mese"; + +"restore.title" = "Ripristina acquisto non accreditato"; +"restore.subtitle" = "Se hai acquistato un piano mediante questa app ma non hai ricevuto le tue credenziali, puoi inviarle nuovamente da qui.\nNon verrà effettuato alcun addebito durante la procedura."; +"restore.email.placeholder" = "Indirizzo email"; +"restore.submit" = "CONFERMA"; + +"iap.error.message.unavailable" = "Server Apple attualmente non disponibili. Riprova più tardi."; +"iap.error.title" = "Errore"; + +"agreement.trials.title" = "Termini e condizioni della prova gratuita"; +"agreement.trials.message" = "Il pagamento verrà addebitato sul tuo account ID Apple alla conferma dell'acquisto. L'abbonamento si rinnova automaticamente a meno che non venga annullato entro 24 ore dalla fine del periodo attuale. Il tuo account verrà addebitato per il rinnovo entro 24 ore dalla fine del periodo attuale. Puoi gestire e cancellare i tuoi abbonamenti dalle impostazioni dell'account sull'App Store dopo l'acquisto.\n\nAlcuni abbonamenti a pagamento possono offrire una prova gratuita prima di addebitare il metodo di pagamento. Se decidi di annullare l'iscrizione a un abbonamento a pagamento prima dell'addebito, dovrai annullarla entro 24 ore dalla scadenza della prova gratuita.\n\nLe prove gratuite sono disponibili solo per i nuovi utenti e sono a nostra esclusiva discrezione. In caso di registrazione per ottenere una prova gratuita aggiuntiva, l'addebito dell'importo standard dell'abbonamento verrà effettuato immediatamente.\n\nCi riserviamo il diritto di revocare la prova gratuita in qualsiasi momento.\n\nQualsiasi parte inutilizzata del periodo di prova gratuito andrà persa al momento dell'acquisto di un abbonamento.\n\nLa registrazione implica l'accettazione dei presenti termini e condizioni."; +"agreement.message" = "Dopo 7 giorni di prova gratuita, l'abbonamento si rinnova automaticamente per % @ a meno che non venga annullato entro 24 ore dalla fine del periodo di prova. Il tuo account ID Apple verrà addebitato per il rinnovo entro 24 ore dalla fine del periodo di prova. Puoi gestire e cancellare i tuoi abbonamenti andando sulle impostazioni del tuo account App Store dopo l'acquisto. L'offerta di prova di 7 giorni è limitata a un'unica offerta da 7 giorni per utente. Ogni parte inutilizzata di un periodo di prova gratuito, se offerto, andrà perduta quando l'utente acquista un abbonamento. Tutti i prezzi includono le tasse locali applicabili.\n\nLa registrazione implica l'accettazione di $1 e $2."; +"agreement.trials.yearly.plan" = "anno"; +"agreement.trials.monthly.plan" = "mese"; + +"agreement.message.tos" = "Termini di servizio"; +"agreement.message.privacy" = "Informativa sulla Privacy"; + +"getstarted.buttons.buyaccount" = "Acquista account"; + +"gdpr.collect.data.title" = "Dati personali da noi raccolti"; +"gdpr.collect.data.description" = "Indirizzo email ai fini di gestione dell'account e della protezione dall'uso improprio."; +"gdpr.usage.data.title" = "Usi delle informazioni personali da noi richieste"; +"gdpr.usage.data.description" = "L'indirizzo email viene utilizzato solo per inviare informazioni sull'abbonamento, conferme di pagamento, corrispondenza col cliente e offerte promozionali di Private Internet Access."; +"gdpr.accept.button.title" = "Accetta e continua"; + +"update.account.email.error" = "Modifica email account non riuscita"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings new file mode 100644 index 000000000..886508935 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "サインアップを確定"; +"in_progress.message" = "システムがご購入を確定しています。しばらく時間がかかることがありますので、そのままお待ちください。"; +"in_progress.redeem.message" = "システムがご購入を確定しています。しばらく時間がかかることがありますので、そのままお待ちください。"; + +"success.title" = "購入完了"; +"success.message_format" = "サインアップありがとうございます。アカウントのユーザー名とパスワードをお客様のメールアドレス(%@)に送信いたしました。"; +"success.redeem.title" = "カードの引き換えが完了しました"; +"success.redeem.message" = "ユーザーネームとパスワードを記載したメールがまもなく届きます。\n\nお客様のログイン詳細"; +"success.username.caption" = "ユーザー名"; +"success.password.caption" = "パスワード"; +"success.submit" = "始める"; + +"failure.vc_title" = "サインアップできませんでした"; +"failure.title" = "アカウントの作成に失敗しました"; +"failure.message" = "ただ今アカウントを作成できません。後ほどもう一度お試しください。\n\nアプリを再起動すると、アカウント作成が再試行されます。"; +"failure.purchase.sandbox.message" = "選択されたサンドボックスのサブスクリプションは生産中のため利用できません。"; +"failure.redeem.invalid.title" = "無効なカードPIN"; +"failure.redeem.invalid.message" = "無効なカードPINを入力したようです。もう一度お試しください。"; +"failure.redeem.claimed.title" = "すでに獲得されたカードです"; +"failure.redeem.claimed.message" = "このカードは、すでに別のアカウントが獲得したようです。別のPINを入力してください。"; +"failure.submit" = "戻る"; + +"unreachable.vc_title" = "エラー"; +"unreachable.title" = "おっと!"; +"unreachable.message" = "インターネット接続が見つかりません。インターネットに接続していることを確認してから下の再試行をタップしてください。\n\n後ほどアプリでこのプロセスを完了することができます。"; +"unreachable.submit" = "再試行"; + +"purchase.uncredited.alert.message" = "反映されていない取引があります。アカウントの詳細を回復しますか?"; +"purchase.uncredited.alert.button.cancel" = "キャンセル"; +"purchase.uncredited.alert.button.recover" = "アカウントを回復"; + +"purchase.trials.intro" = "7日間無料トライアルを開始"; +"purchase.trials.price.after" = "以後%@"; +"purchase.trials.money.back" = "30日間返金保証"; +"purchase.trials.1year.protection" = "1年間のプライバシーおよび個人情報の保護"; +"purchase.trials.anonymous" = "ウェブの匿名利用でIPを非表示にします。"; +"purchase.trials.devices" = "一度に10台の端末をサポート"; +"purchase.trials.devices.description" = "一度に最大10台の端末を保護して自分を守ることができます。"; +"purchase.trials.region" = "すべての地域に簡単に接続"; +"purchase.trials.servers" = "32か国の3300以上のサーバー"; +"purchase.trials.start" = "サブスクリプションを開始"; +"purchase.trials.all.plans" = "利用可能なプランをすべて見る"; + +"purchase.subscribe.now" = "今すぐ定期購読を購入"; + +// WALKTHROUGH + +"walkthrough.action.next" = "次へ"; +"walkthrough.action.done" = "完了"; +"walkthrough.action.skip" = "スキップ"; + +"walkthrough.page.1.title" = "一度に10台の端末をサポート"; +"walkthrough.page.1.description" = "一度に最大10台の端末を保護して自分を守ることができます。"; +"walkthrough.page.2.title" = "あらゆる地域に簡単に接続"; +"walkthrough.page.2.description" = "世界中にサーバがあるので、常に保護された状態でいることができます。"; +"walkthrough.page.3.title" = "広告から自分を守りましょう"; +"walkthrough.page.3.description" = "コンテンツブロッカーを有効にすると、Safariで広告表示をブロックできます。"; + +"share.data.buttons.accept" = "同意する"; +"share.data.buttons.noThanks" = "いいえ、結構です"; +"share.data.buttons.readMore" = "もっと読む"; +"share.data.text.title" = "弊社のサービス改善にご協力ください"; +"share.data.text.description" = "弊社のサービスの接続パフォーマンス確保にご協力いただくには、接続データを匿名で弊社と共有してください。これらのレポートには、個人を特定できる情報は含まれません。"; +"share.data.text.footer" = "これは、設定からいつでもコントロール可能です"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings new file mode 100644 index 000000000..1751458e6 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "バージョン%@ (%@)"; +"global.close" = "閉じる"; +"global.ok" = "OK"; +"global.cancel" = "キャンセル"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings new file mode 100644 index 000000000..98aa77a8f --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "アカウントにサインイン"; +"login.username.placeholder" = "ユーザー名 (p1234567)"; +"login.password.placeholder" = "パスワード"; +"login.submit" = "ログイン"; +"login.restore.button" = "アカウント詳細を受信しませんでしたか?"; +"login.error.title" = "ログイン"; +"login.error.validation" = "ユーザー名とパスワードを入力してください。"; +"login.error.unauthorized" = "ユーザー名またはパスワードが間違っています。"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "購入領収書を使用してログイン"; +"login.magic.link.title" = "魔法のメールリンクを使用してログイン"; +"login.magic.link.response" = "ログインリンクについては、メールを確認してください。"; +"login.magic.link.send" = "リンクを送信"; +"login.magic.link.invalid.email" = "無効なメールアドレス。もう一度お試しください。"; + +"purchase.title" = "VPNプランを選択"; +"purchase.subtitle" = "30日間返金保証"; +"purchase.email.placeholder" = "メールアドレス"; +"purchase.continue" = "続行"; +"purchase.login.footer" = "既にアカウントをお持ちですか?"; +"purchase.login.button" = "サインイン"; +"purchase.error.title" = "購入"; +"purchase.error.validation" = "必ずメールアドレスを入力してください。"; +"purchase.error.connectivity.title" = "接続エラー"; +"purchase.error.connectivity.description" = "Private Internet Accessに接続できませんでした。インターネットの接続が不安定、もしくはお住まいの国で当社サービスがブロックされている可能性があります。"; +"purchase.confirm.form.email" = "メールアドレスを入力してください"; +"purchase.confirm.plan" = "お客様は%@プランを購入しようとしています"; +"purchase.email.why" = "ユーザー名とパスワードを送信するためのメールアドレスを入力してください。"; +"purchase.submit" = "送信"; +"purchase.or" = "または"; + +"upgrade.header" = "お帰りなさい!"; +"upgrade.title" = "Private Internet Accessのご利用を継続するには、サブスクリプションを更新する必要があります。"; +"upgrade.renew.now" = "今すぐ更新"; + + + +"redeem.title" = "ギフトカード引換え"; +"redeem.subtitle" = "メールアドレスと、以下のギフトカードまたはトライアルカードの%lu桁のPINを入力してください。"; +"redeem.email.placeholder" = "メールアドレス"; +"redeem.submit" = "送信"; +"redeem.error.title" = "引換え"; +"redeem.error.code" = "コードは%lu桁でなければなりません。"; +"redeem.error.allfields" = "メールアドレスとカードのPINを入力してください。"; +"redeem.accessibility.back" = "戻る"; +"redeem.giftcard.placeholder" = "ギフトカードのPIN"; + +"plan.monthly.title" = "月間"; +"plan.yearly.title" = "年間"; +"plan.yearly.detail_format" = "年間%@%@"; +"plan.price_format" = "%@/月"; +"plan.best_value" = "最もお得"; +"plan.accessibility.per_month" = "月々"; + +"restore.title" = "追加されていない更新を復元"; +"restore.subtitle" = "このアプリでプランを購入した後、認証情報を受け取っていない方は、こちらから認証情報を再度送信することができます。この処理の実行中、課金は発生しません。"; +"restore.email.placeholder" = "メールアドレス"; +"restore.submit" = "確定"; + +"iap.error.message.unavailable" = "Appleサーバーが現在ご利用いただけません。後でもう一度お試しください。"; +"iap.error.title" = "エラー"; + +"agreement.trials.title" = "無料トライアル利用規約"; +"agreement.trials.message" = "ご購入確定時にお使いのApple IDアカウント支払額が請求されます。サブスクリプションは現在の期間が終了する24時間前までにキャンセルされない限り自動的に更新されます。更新料は現在の期間終了前の24時間以内にお使いのアカウントに請求されます。サブスクリプションはご購入後にApp Storeのアカウント設定からいつでも管理およびキャンセルすることができます。\n\n一部の有料サブスクリプションでは、ご希望の支払方法による請求が実施される前に無料トライアルが提供されている場合があります。ご選択の支払方法による請求が実施される前に有料サブスクリプションの解約をする場合は、無料トライアルが終了する24時間前までにサブスクリプションをキャンセルしてください。\n\n無料トライアルをご利用いただけるのは新規ユーザーのみとなり、無料トライアルを使用する目的で新たに追加のアカウントをサインアップした場合、弊社の裁量によって、通常のサブスクリプション料金が即時に請求されます。\n\n弊社は無料トライアル期間をいつでも無効にする権利を保持します。\n\nサブスクリプションご購入後、未使用分の無料トライアル期間は無効となります。\n\nサインアップすることで、$1と$2に同意したことになります。"; +"agreement.message" = "トライアル期間終了の少なくとも24時間前にキャンセルされない限り、7日間の無料トライアル後、この定期購読は自動的に%@で更新されます。更新料は、トライアル期間終了前の24時間以内にご利用のApple IDアカウントに請求されます。定期購読は、定期購読購入後にApp Storeアカウント設定から管理およびキャンセルすることができます。7日間のトライアルオファーは、ユーザー1人あたり1回の7日間トライアルに限られています。無料トライアルを利用した場合、無料トライアル期間の未使用分は、ユーザーが定期購読を購入した時点で無効となります。すべての料金には、適用可能な場合現地の消費税が含まれます。\n\nサインアップすることにより、$1および$2に同意したことになります。"; +"agreement.trials.yearly.plan" = "年"; +"agreement.trials.monthly.plan" = "月"; + +"agreement.message.tos" = "利用規約"; +"agreement.message.privacy" = "プライバシーポリシー"; + +"getstarted.buttons.buyaccount" = "アカウントを購入する"; + +"gdpr.collect.data.title" = "弊社が収集する個人情報"; +"gdpr.collect.data.description" = "メールアドレスは、アカウント管理、および乱用からの保護を目的とします。"; +"gdpr.usage.data.title" = "弊社により収集される個人情報の使用"; +"gdpr.usage.data.description" = "メールアドレスはサブスクリプション情報、お支払確認、お客様とのやり取り、およびPrivate Internet Accessのプロモーションオファーを送信するためにのみ使用されます。"; +"gdpr.accept.button.title" = "同意して続行する"; + +"update.account.email.error" = "アカウントのメールを変更できませんでした"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings new file mode 100644 index 000000000..cfd62453f --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "회원 가입 확인"; +"in_progress.message" = "저희 시스템에서 고객님의 구매를 확인하고 있습니다. 약간 시간이 소요될 수 있으므로 양해 부탁드립니다."; +"in_progress.redeem.message" = "저희 시스템에서 고객님의 카드 PIN을 확인하고 있습니다. 약간 시간이 소요될 수 있으므로 양해 부탁드립니다."; + +"success.title" = "구매 완료"; +"success.message_format" = "회원으로 가입해 주셔서 감사합니다. 계정 사용자명과 비밀번호를 귀하의 이메일 주소(%@)로 발송했습니다."; +"success.redeem.title" = "카드 사용 성공"; +"success.redeem.message" = "사용자 이름 및 비밀번호가 담긴 이메일을 곧 보내드리겠습니다.\n\n귀하의 로그인 정보"; +"success.username.caption" = "사용자 이름"; +"success.password.caption" = "비밀번호"; +"success.submit" = "시작하기"; + +"failure.vc_title" = "회원 가입 실패"; +"failure.title" = "계정 생성 실패"; +"failure.message" = "지금은 계정을 생성할 수 없습니다. 나중에 다시 시도해주십시오.\n\n 앱을 다시 열면 계정 생성을 다시 시도합니다."; +"failure.purchase.sandbox.message" = "선택하신 샌드박스 구독은 생산에 사용할 수 없습니다."; +"failure.redeem.invalid.title" = "유효하지 않은 카드 PIN"; +"failure.redeem.invalid.message" = "유효하지 않은 카드 PIN을 입력한 것 같습니다. 다시 시도하세요."; +"failure.redeem.claimed.title" = "이미 청구한 카드"; +"failure.redeem.claimed.message" = "이 카드는 이미 다른 계정에서 청구한 것 같습니다. 다른 PIN을 입력해 보세요."; +"failure.submit" = "뒤로"; + +"unreachable.vc_title" = "오류"; +"unreachable.title" = "앗!"; +"unreachable.message" = "인터넷에 연결되지 않았습니다. 인터넷에 연결되어 있는지 확인하신 후 아래에서 다시 시도를 누르십시오.\n\n나중에 앱에 다시 돌아와서 이 과정을 완료할 수 있습니다."; +"unreachable.submit" = "다시 시도"; + +"purchase.uncredited.alert.message" = "처리되지 않은 거래가 있습니다. 계정 정보를 복구하시겠습니까?"; +"purchase.uncredited.alert.button.cancel" = "취소"; +"purchase.uncredited.alert.button.recover" = "계정 복구"; + +"purchase.trials.intro" = "7일 무료 체험 시작"; +"purchase.trials.price.after" = "그 후 %@"; +"purchase.trials.money.back" = "30일 이내 환불 보장"; +"purchase.trials.1year.protection" = "1년간 프라이버시 및 신원 보호"; +"purchase.trials.anonymous" = "익명으로 검색하고 IP를 숨기세요."; +"purchase.trials.devices" = "동시에 10대의 장치 지원"; +"purchase.trials.devices.description" = "한 번에 최대 10대의 장치에서 보호를 받으세요."; +"purchase.trials.region" = "모든 지역에 쉽게 연결"; +"purchase.trials.servers" = "32개국 3300개 이상의 서버"; +"purchase.trials.start" = "구독 시작"; +"purchase.trials.all.plans" = "이용 가능한 모든 플랜 보기"; + +"purchase.subscribe.now" = "지금 구독"; + +// WALKTHROUGH + +"walkthrough.action.next" = "다음"; +"walkthrough.action.done" = "완료"; +"walkthrough.action.skip" = "건너뛰기"; + +"walkthrough.page.1.title" = "한 번의 10대의 장치 지원"; +"walkthrough.page.1.description" = "한 번에 최대 10대의 장치에서 보호를 받으세요."; +"walkthrough.page.2.title" = "모든 지역에 쉽게 연결"; +"walkthrough.page.2.description" = "전 세계에 있는 서버를 통해 언제나 보호를 받습니다."; +"walkthrough.page.3.title" = "광고로부터 보호"; +"walkthrough.page.3.description" = "Content Blocker를 활성화하면 Safari에서 광고가 표시되지 않습니다."; + +"share.data.buttons.accept" = "수락"; +"share.data.buttons.noThanks" = "아니요"; +"share.data.buttons.readMore" = "자세히 보기"; +"share.data.text.title" = "저희 서비스를 개선하도록 도와 주세요"; +"share.data.text.description" = "연결 상태를 저희와 익명으로 공유해 주시면 저희 서비스의 연결 성능을 개선하는 데 도움이 됩니다. 이 보고서에는 개인 식별 정보가 포함되지 않습니다."; +"share.data.text.footer" = "언제든지 설정에서 이 옵션을 관리할 수 있습니다."; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings new file mode 100644 index 000000000..1c9f1e509 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "버전 %@ (%@)"; +"global.close" = "닫기"; +"global.ok" = "확인"; +"global.cancel" = "취소"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings new file mode 100644 index 000000000..2d29b5f83 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "계정에 로그인"; +"login.username.placeholder" = "사용자 이름 (p1234567)"; +"login.password.placeholder" = "비밀번호"; +"login.submit" = "로그인"; +"login.restore.button" = "계정 정보를 받지 못하셨습니까?"; +"login.error.title" = "로그인"; +"login.error.validation" = "사용자 이름과 비밀번호를 입력하셔야 합니다."; +"login.error.unauthorized" = "사용자명 또는 비밀번호가 틀립니다."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "구매 영수증을 사용해 로그인"; +"login.magic.link.title" = "이메일 링크를 사용해 간편하게 로그인"; +"login.magic.link.response" = "로그인 링크가 담긴 이메일을 확인하세요."; +"login.magic.link.send" = "링크 보내기"; +"login.magic.link.invalid.email" = "이메일이 유효하지 않음. 다시 시도하세요."; + +"purchase.title" = "VPN 플랜 선택"; +"purchase.subtitle" = "30일 이내 환불 보장"; +"purchase.email.placeholder" = "이메일 주소"; +"purchase.continue" = "계속"; +"purchase.login.footer" = "이미 계정이 있으세요?"; +"purchase.login.button" = "로그인"; +"purchase.error.title" = "구매"; +"purchase.error.validation" = "이메일 주소를 입력하셔야 합니다."; +"purchase.error.connectivity.title" = "연결 실패"; +"purchase.error.connectivity.description" = "Private Internet Access에 접속할 수 없습니다. 인터넷 연결 상태가 좋지 않거나 귀하의 국가에서 당사의 서비스가 차단된 것 같습니다."; +"purchase.confirm.form.email" = "이메일 주소를 입력하세요"; +"purchase.confirm.plan" = "%@ 플랜을 구매합니다"; +"purchase.email.why" = "사용자 이름 및 비밀번호를 보내 드리면 고객님의 이메일 주소가 필요합니다."; +"purchase.submit" = "제출"; +"purchase.or" = "또는"; + +"upgrade.header" = "다시 오신 걸 환영합니다!"; +"upgrade.title" = "Private Internet Access를 사용하려면 구독을 갱신하셔야 합니다."; +"upgrade.renew.now" = "지금 갱신"; + + + +"redeem.title" = "기프트 카드 청구"; +"redeem.subtitle" = "기프트 카드 또는 체험 카드의 %lu자리 PIN과 이메일 주소를 입력하세요."; +"redeem.email.placeholder" = "이메일 주소"; +"redeem.submit" = "제출"; +"redeem.error.title" = "청구"; +"redeem.error.code" = "코드는 %lu자리 숫자여야 합니다."; +"redeem.error.allfields" = "이메일 및 카드 PIN을 입력하세요."; +"redeem.accessibility.back" = "뒤로"; +"redeem.giftcard.placeholder" = "기프트 카드 PIN"; + +"plan.monthly.title" = "월간"; +"plan.yearly.title" = "연간"; +"plan.yearly.detail_format" = "매년 %@%@"; +"plan.price_format" = "%@/월"; +"plan.best_value" = "최저가"; +"plan.accessibility.per_month" = "매월"; + +"restore.title" = "인정되지 않은 구매 항목 복원"; +"restore.subtitle" = "이 앱을 통해 요금 플랜을 구매하셨는데 자격 증명 정보를 받지 못하신 경우 이곳에서 다시 보내실 수 있습니다. 이 과정 중 요금이 부과되지 않습니다.\n"; +"restore.email.placeholder" = "이메일 주소"; +"restore.submit" = "확인"; + +"iap.error.message.unavailable" = "현재 Apple 서버를 이용할 수 없습니다. 나중에 다시 시도해주십시오."; +"iap.error.title" = "오류"; + +"agreement.trials.title" = "무료 체험 계약 조건"; +"agreement.trials.message" = "구매 확인 시 사용자의 Apple ID 계정으로 요금이 청구됩니다. 현재 기간이 종료하기 24시간 전에 취소하지 않으면 구독은 자동으로 갱신됩니다. 현재 기간이 종료하기 전 24시간 이내에 갱신 요금이 계정으로 청구됩니다. 구매 후 App Store의 계정 설정에서 구독을 관리하고 취소할 수 있습니다.\n\n일부 유료 구독은 사용자의 결제 수단으로 청구하기 전에 무료 체험을 제공할 수 있습니다. 결제 수단으로 청구가 시작되기 전에 유료 구독을 취소하려면, 무료 체험 기간이 종료하기 24시간 전에 구독을 취소하십시오.\n\n무료 체험은 신규 사용자만 이용할 수 있으며, 당사의 단독 재량으로 제공됩니다. 무료 체험을 추가로 이용하기 위해 가입한 경우 표준 구독 요금이 즉시 청구됩니다.\n\n당사는 언제든지 무료 체험을 철회할 권리를 보유합니다.\n\n구독 구매 시 무료 체험 기간의 미사용분은 소멸됩니다.\n\n가입 시 본 계약 조건에 동의하신 것으로 간주됩니다."; +"agreement.message" = "체험 기간이 종료하기 24시간 전에 구독을 취소하지 않으면, 7일 무료 체험 후 이 구독은 %@에 자동으로 갱신됩니다. 체험 기간이 종료하기 전 24시간 이내에 사용자의 Apple ID로 갱신 요금이 청구됩니다. 구매 후 App Store 계정으로 이동하여 구독을 관리하고 취소할 수 있습니다. 7일 체험 혜택은 사용자당 한 번으로 제한됩니다. 사용자가 구독을 구매할 경우 무료 체험 기간의 미사용분은 소멸됩니다. 모든 가격에는 현지에서 적용되는 판매세가 포함됩니다.\n\n가입 시 $1 및 $2에 동의하신 것으로 간주됩니다."; +"agreement.trials.yearly.plan" = "년"; +"agreement.trials.monthly.plan" = "개월"; + +"agreement.message.tos" = "서비스 약관"; +"agreement.message.privacy" = "개인정보 취급방침"; + +"getstarted.buttons.buyaccount" = "계정 구입"; + +"gdpr.collect.data.title" = "당사가 수집하는 개인 정보"; +"gdpr.collect.data.description" = "계정 관리 및 악용 방지를 위한 이메일 주소."; +"gdpr.usage.data.title" = "수집된 개인 정보의 사용"; +"gdpr.usage.data.description" = "이메일 주소는 구독 정보, 결제 확인, 고객 공지 사항 및 Private Internet Access 프로모션 정보를 보내는 데에만 사용됩니다."; +"gdpr.accept.button.title" = "동의 및 계속"; + +"update.account.email.error" = "계정 이메일을 수정하지 못했습니다"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings new file mode 100644 index 000000000..300d513ed --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Bekrefter registrering"; +"in_progress.message" = "Vi bekrefter kjøpet i systemet vårt. Dette kan ta litt tid."; +"in_progress.redeem.message" = "Vi bekrefter kort-PIN-en din i systemet vårt. Det kan ta et øyeblikk, så vennligst vent."; + +"success.title" = "Kjøp fullført"; +"success.message_format" = "Takk for at du registrerte deg. Vi har sendt deg kontonavnet og passordet ditt til e-postadressen din %@"; +"success.redeem.title" = "Kortet har blitt innløst"; +"success.redeem.message" = "Du mottar en e-post med brukernavn og passord.\n\nPåloggingsinformasjonen din"; +"success.username.caption" = "Brukernavn"; +"success.password.caption" = "Passord"; +"success.submit" = "Komme i gang"; + +"failure.vc_title" = "Registrering mislyktes"; +"failure.title" = "Kunne ikke opprette kontoen"; +"failure.message" = "Vi kunne ikke opprette en konto nå. Prøv på nytt senere.\n\nNår du åpner appen igjen, vil den prøve å opprette kontoen på nytt."; +"failure.purchase.sandbox.message" = "Det valgte sandboksabonnementet er ikke tilgjengelig i produksjon."; +"failure.redeem.invalid.title" = "Ugyldig kort-PIN"; +"failure.redeem.invalid.message" = "Ser ut til at du brukte en ugyldig kort-PIN. Prøv igjen"; +"failure.redeem.claimed.title" = "Kortet er allerede brukt"; +"failure.redeem.claimed.message" = "Ser ut til at kortet allerede er brukt av en annen konto. Du kan prøve med en annen PIN."; +"failure.submit" = "GÅ TILBAKE"; + +"unreachable.vc_title" = "Feil"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Ingen internettilkobling. Bekreft at du er koblet til Internett og trykk på Prøv igjen nedenfor.\n\nDu kan komme tilbake til appen senere for å fullføre prosessen."; +"unreachable.submit" = "PRØV PÅ NYTT"; + +"purchase.uncredited.alert.message" = "Du har ikke krediterte transaksjoner. Vil du gjenopprette kontoinformasjonen din?"; +"purchase.uncredited.alert.button.cancel" = "Abryt"; +"purchase.uncredited.alert.button.recover" = "Gjenopprett konto"; + +"purchase.trials.intro" = "Start din gratis 7-dagers prøveperiode"; +"purchase.trials.price.after" = "Deretter %@"; +"purchase.trials.money.back" = "30 dagers pengene-tilbake-garanti"; +"purchase.trials.1year.protection" = "Et års personverns- og identitetsbeskyttelse"; +"purchase.trials.anonymous" = "Surf anonymt og skjul IP-adressen din."; +"purchase.trials.devices" = "Støtter ti enheter om gangen"; +"purchase.trials.devices.description" = "Beskytt deg på opptil ti enheter samtidig."; +"purchase.trials.region" = "Koble til hvilken som helst region på en enkel måte"; +"purchase.trials.servers" = "Over 3300 servere i 32 land"; +"purchase.trials.start" = "Start abonnementet"; +"purchase.trials.all.plans" = "Vis alle tilgjengelige abonnement"; + +"purchase.subscribe.now" = "Abonner nå"; + +// WALKTHROUGH + +"walkthrough.action.next" = "NESTE"; +"walkthrough.action.done" = "FERDIG"; +"walkthrough.action.skip" = "HOPP OVER"; + +"walkthrough.page.1.title" = "Støtter ti enheter samtidig"; +"walkthrough.page.1.description" = "Beskytt deg på opptil ti enheter samtidig."; +"walkthrough.page.2.title" = "Koble til hvilken som helst region på en enkel måte"; +"walkthrough.page.2.description" = "Med serverer rundt om i hele verden, er du alltid beskyttet."; +"walkthrough.page.3.title" = "Beskytt deg selv mot reklame"; +"walkthrough.page.3.description" = "Aktivering av innholdsblokkereren sikrer at reklame ikke blir vist når du bruker Safari."; + +"share.data.buttons.accept" = "Godta"; +"share.data.buttons.noThanks" = "Nei takk"; +"share.data.buttons.readMore" = "Les mer"; +"share.data.text.title" = "Hjelp oss med å forbedre tjenesten vår"; +"share.data.text.description" = "For å hjelpe oss med å sikre tjenestens tilkoblingsytelse, kan du anonymt dele tilkoblingsstatistikken din med oss. Disse rapportene inkluderer informasjon som ikke er personlig identifiserbar."; +"share.data.text.footer" = "Du kan kontrollere dette fra innstillingene dine"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings new file mode 100644 index 000000000..5ccb0d7dc --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versjon %@ (%@)"; +"global.close" = "Lukk"; +"global.ok" = "OK"; +"global.cancel" = "Avbryt"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings new file mode 100644 index 000000000..80faed974 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Logg inn på kontoen din"; +"login.username.placeholder" = "Brukernavn (p1234567)"; +"login.password.placeholder" = "Passord"; +"login.submit" = "LOGG INN"; +"login.restore.button" = "Har du ikke fått kontodetaljene?"; +"login.error.title" = "Logg på"; +"login.error.validation" = "Du må oppgi et brukernavn og passord."; +"login.error.unauthorized" = "Brukernavnet eller passordet ditt er feil."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Logg på med kjøpsbevis"; +"login.magic.link.title" = "Pålogging med magisk e-postkobling"; +"login.magic.link.response" = "Sjekk e-posten din for å finne påloggingskoblingen."; +"login.magic.link.send" = "Send kobling"; +"login.magic.link.invalid.email" = "Ugyldig e-post. Prøv igjen."; + +"purchase.title" = "Velg et VPN-abonnement"; +"purchase.subtitle" = "30 dagers pengene-tilbake-garanti"; +"purchase.email.placeholder" = "E-postadresse"; +"purchase.continue" = "Fortsett"; +"purchase.login.footer" = "Har du allerede en konto?"; +"purchase.login.button" = "Logg inn"; +"purchase.error.title" = "Kjøp"; +"purchase.error.validation" = "Du må angi en e-postadresse."; +"purchase.error.connectivity.title" = "Tilkoblingsfeil"; +"purchase.error.connectivity.description" = "Vi kunne ikke nå Private Internet Access. Dette kan skyldes dårlig Internett eller at tjenesten vår er blokkert i landet ditt."; +"purchase.confirm.form.email" = "Angi e-postadressen din"; +"purchase.confirm.plan" = "Du kjøper %@-abonnementet"; +"purchase.email.why" = "Vi trenger e-posten din for å sende deg brukernavnet og passordet ditt."; +"purchase.submit" = "Send inn"; +"purchase.or" = "eller"; + +"upgrade.header" = "Velkommen tilbake!"; +"upgrade.title" = "For å bruke en privat internettilgang, må du fornye abonnementet ditt."; +"upgrade.renew.now" = "Forny nå"; + + + +"redeem.title" = "Løs inn gavekort"; +"redeem.subtitle" = "Angi e-postadressen og den %lu-sifrede PIN-koden fra gavekortet eller prøvekortet nedenfor."; +"redeem.email.placeholder" = "E-postadresse"; +"redeem.submit" = "SEND"; +"redeem.error.title" = "Løs inn"; +"redeem.error.code" = "Koden må bestå av %lu siffer."; +"redeem.error.allfields" = "Angi e-postadressen din og kortet PIN-kode."; +"redeem.accessibility.back" = "Tilbake"; +"redeem.giftcard.placeholder" = "PIN-kode for gavekort"; + +"plan.monthly.title" = "Månedlig"; +"plan.yearly.title" = "Årlig"; +"plan.yearly.detail_format" = "%@%@ per år"; +"plan.price_format" = "%@/mnd"; +"plan.best_value" = "Mest for pengene"; +"plan.accessibility.per_month" = "per måned"; + +"restore.title" = "Gjenopprett ukreditert kjøp"; +"restore.subtitle" = "Hvis du har kjøpt en plan via appen og ikke har mottatt opplysningene dine, kan du sende dem på nytt herfra.\nDu belastes ikke under denne prosessen."; +"restore.email.placeholder" = "E-postadresse"; +"restore.submit" = "BEKREFT"; + +"iap.error.message.unavailable" = "Apple-serverne er for øyeblikket ikke tilgjengelige. Prøv igjen senere."; +"iap.error.title" = "Feil"; + +"agreement.trials.title" = "Vilkår og betingelser for gratis prøveperiode"; +"agreement.trials.message" = "Betalingen belastes Apple ID-kontoen din når du bekrefter kjøpet. Abonnementet fornyes automatisk med mindre det kanselleres minst 24 timer før slutten av den inneværende perioden. Kontoen blir belastet for fornyelse innen 24 timer før slutten av den inneværende perioden. Du kan administrere og kansellere abonnementene dine ved besøke kontoinnstillingene på App Store etter kjøpet.\n\nEnkelte betalte abonnementer kan tilby en gratis prøveperiode før det belaster betalingsmetoden din. Hvis du bestemmer deg for å avslutte et betalt abonnement før vi begynner å belaste betalingsmetoden din, må du kansellere abonnementet minst 24 timer før prøveperioden er slutt.\n\nGratis prøveperioder er kun tilgjengelig for nye brukere og utføres etter vårt eget skjønn. Hvis du forsøker å registrere deg med flere gratis prøveperioder, blir du øyeblikkelig belastet standard abonnementsavgift.\n\nVi forbeholder oss retten til å tilbakekalle din gratis prøveperiode når som helst.\n\nEventuell ubrukt del av en gratis prøveperiode går tapt ved kjøpe av et abonnement.\n\nVed å registrere deg samtykker du til disse vilkårene og betingelsene."; +"agreement.message" = "Etter den gratis 7-dagers prøveperioden fornyes abonnementet automatisk for %@, med mindre det kanselleres minst 24 timer før slutten av prøveperioden. Din Apple ID-konto belastes for fornyingen innen 24 timer før slutten av prøveperioden. Du kan administrere og avbryte abonnementene dine ved å gå til App Store-kontoinnstillingene etter kjøp. Det 7-dagers prøvetilbudet er begrenset til én 7-dagers prøveperiode per bruker. Eventuell ubrukt tid av den gratis prøveperioden går tapt hvis brukeren kjøper et abonnement. Alle priser inkluderer gjeldende lokale avgifter.\n\nVed å signere godtar du $1 og $2."; +"agreement.trials.yearly.plan" = "år"; +"agreement.trials.monthly.plan" = "måned"; + +"agreement.message.tos" = "Tjenestevilkår"; +"agreement.message.privacy" = "REntingslinjer om personvern"; + +"getstarted.buttons.buyaccount" = "Kjøpskonto"; + +"gdpr.collect.data.title" = "Personlig informasjon vi tar vare på"; +"gdpr.collect.data.description" = "E-postadresse for kontoadministrasjon og beskyttelse mot misbruk."; +"gdpr.usage.data.title" = "Bruk av personlig informasjon samlet inn av oss"; +"gdpr.usage.data.description" = "E-postadresse blir kun brukt for å sende ut informasjon om abonnementet, betalingsbekreftelser, kundekorrespondanse og tilbud om privat internettilgang."; +"gdpr.accept.button.title" = "Godta og fortsett"; + +"update.account.email.error" = "Kunne ikke endre kontoens e-post"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings new file mode 100644 index 000000000..97c63fd93 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Aanmelding bevestigen"; +"in_progress.message" = "We zijn uw aankoop aan het verifiëren in ons systeem. Dit kan eventjes duren, daarom vragen we u vriendelijk om geduld."; +"in_progress.redeem.message" = "We zijn uw pincode aan het verifiëren in ons systeem. Dit kan eventjes duren, daarom vragen we u vriendelijk om geduld."; + +"success.title" = "Aankoop voltooid"; +"success.message_format" = "Bedankt voor uw aanmelding. We hebben de gebruikersnaam en het wachtwoord voor uw account naar het volgende e-mailadres gestuurd: %@"; +"success.redeem.title" = "Kaart ingewisseld"; +"success.redeem.message" = "U ontvangt zo een e-mail met uw gebruikersnaam en wachtwoord."; +"success.username.caption" = "Gebruikersnaam"; +"success.password.caption" = "Wachtwoord"; +"success.submit" = "Aan de slag"; + +"failure.vc_title" = "Aanmelden mislukt"; +"failure.title" = "Account aanmaken mislukt"; +"failure.message" = "We kunnen op dit moment geen account maken. Probeer het later opnieuw. \n\nAls u de app opnieuw opent, wordt opnieuw geprobeerd een account te maken."; +"failure.purchase.sandbox.message" = "Het geselecteerde sandbox-abonnement is niet beschikbaar in productie."; +"failure.redeem.invalid.title" = "Ongeldige pincode"; +"failure.redeem.invalid.message" = "U heeft een ongeldige pincode ingevoerd. Probeer het opnieuw."; +"failure.redeem.claimed.title" = "Kaart al geclaimd"; +"failure.redeem.claimed.message" = "Deze kaart is door een ander account geclaimd. Probeer een andere pincode."; +"failure.submit" = "GA TERUG"; + +"unreachable.vc_title" = "Fout"; +"unreachable.title" = "Oeps!"; +"unreachable.message" = "Geen internetverbinding gevonden. Controleer uw internetverbinding en probeer het hieronder opnieuw.\n\nU kunt later naar de app terugkeren om het proces te voltooien."; +"unreachable.submit" = "OPNIEUW PROBEREN"; + +"purchase.uncredited.alert.message" = "U heeft niet-gecrediteerde transacties. Wilt u uw accountgegevens herstellen?"; +"purchase.uncredited.alert.button.cancel" = "Annuleren"; +"purchase.uncredited.alert.button.recover" = "Account herstellen"; + +"purchase.trials.intro" = "Start je gratis proefabonnement van 7 dagen"; +"purchase.trials.price.after" = "Daarna %@"; +"purchase.trials.money.back" = "30 dagen lang niet-goed-geld-teruggarantie"; +"purchase.trials.1year.protection" = "1 jaar aan privacy- en identiteitsbescherming"; +"purchase.trials.anonymous" = "Browse anoniem en verberg uw ip."; +"purchase.trials.devices" = "Ondersteun tien apparaten tegelijk"; +"purchase.trials.devices.description" = "Bescherm uzelf op tien apparaten tegelijk."; +"purchase.trials.region" = "Maak eenvoudig verbinding met elke regio"; +"purchase.trials.servers" = "Meer dan 3300 servers in 32 landen"; +"purchase.trials.start" = "Abonnement starten"; +"purchase.trials.all.plans" = "Bekijk de beschikbare abonnementen"; + +"purchase.subscribe.now" = "Nu abonneren"; + +// WALKTHROUGH + +"walkthrough.action.next" = "VOLGENDE"; +"walkthrough.action.done" = "KLAAR"; +"walkthrough.action.skip" = "OVERSLAAN"; + +"walkthrough.page.1.title" = "Ondersteun tien apparaten tegelijk"; +"walkthrough.page.1.description" = "Bescherm uzelf op tien apparaten tegelijk."; +"walkthrough.page.2.title" = "Maak eenvoudig verbinding met elke regio"; +"walkthrough.page.2.description" = "Met servers over de hele wereld wordt u altijd beschermd."; +"walkthrough.page.3.title" = "Bescherm uzelf tegen advertenties"; +"walkthrough.page.3.description" = "Als u onze Content Blocker inschakelt, krijgt u geen advertenties meer te zien in Safari."; + +"share.data.buttons.accept" = "Accepteren"; +"share.data.buttons.noThanks" = "Nee, bedankt"; +"share.data.buttons.readMore" = "Meer informatie"; +"share.data.text.title" = "Help ons onze service te verbeteren"; +"share.data.text.description" = "Om ons te helpen de verbindingsprestaties van onze dienst te verbeteren, kunt u uw verbindingsstatistieken anoniem met ons delen. Deze rapporten bevatten geen persoonsgegevens."; +"share.data.text.footer" = "U kunt dit via de Instellingen beheren"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings new file mode 100644 index 000000000..0131eaac3 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versie %@ (%@)"; +"global.close" = "Sluiten"; +"global.ok" = "OK"; +"global.cancel" = "Annuleren"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings new file mode 100644 index 000000000..3c4007de5 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Aanmelden bij uw account"; +"login.username.placeholder" = "Gebruikersnaam (p1234567)"; +"login.password.placeholder" = "Wachtwoord"; +"login.submit" = "INLOGGEN"; +"login.restore.button" = "Geen accountgegevens ontvangen?"; +"login.error.title" = "Inloggen"; +"login.error.validation" = "U moet een gebruikersnaam en wachtwoord invoeren."; +"login.error.unauthorized" = "Uw gebruikersnaam of wachtwoord is onjuist."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Inloggen met aankoopbewijs"; +"login.magic.link.title" = "Log in met de magische link in uw e-mail"; +"login.magic.link.response" = "Controleer uw e-mail voor een inloglink."; +"login.magic.link.send" = "Link verzenden"; +"login.magic.link.invalid.email" = "Ongeldige e-mail. Probeer het opnieuw."; + +"purchase.title" = "Selecteer een VPN-abonnement"; +"purchase.subtitle" = "30 dagen lang niet-goed-geld-teruggarantie"; +"purchase.email.placeholder" = "E-mailadres"; +"purchase.continue" = "Doorgaan"; +"purchase.login.footer" = "Heeft u al een account?"; +"purchase.login.button" = "Aanmelden"; +"purchase.error.title" = "Kopen"; +"purchase.error.validation" = "U moet een e-mailadres invoeren"; +"purchase.error.connectivity.title" = "Verbindingsfout"; +"purchase.error.connectivity.description" = "We kunnen Private Internet Access niet bereiken. Dit kan komen door een slechte internetverbinding of omdat onze dienst in uw land is geblokkeerd."; +"purchase.confirm.form.email" = "Voer uw e-mailadres in"; +"purchase.confirm.plan" = "U koop het %@-abonnement"; +"purchase.email.why" = "We hebben uw e-mailadres nodig om uw gebruikersnaam en wachtwoord te versturen."; +"purchase.submit" = "Versturen"; +"purchase.or" = "of"; + +"upgrade.header" = "Welkom terug!"; +"upgrade.title" = "U moet uw abonnement vernieuwen om Private Internet Access te kunnen gebruiken."; +"upgrade.renew.now" = "Nu vernieuwen"; + + + +"redeem.title" = "Cadeaubon inwisselen"; +"redeem.subtitle" = "Voer uw e-mailadres en de %lu-cijferige pincode van uw cadeaubon of proefperiodekaart hieronder in."; +"redeem.email.placeholder" = "E-mailadres"; +"redeem.submit" = "VERSTUREN"; +"redeem.error.title" = "Inwisselen"; +"redeem.error.code" = "Code moet uit %lu getallen bestaan."; +"redeem.error.allfields" = "Voer uw e-mailadres en pincode in."; +"redeem.accessibility.back" = "Terug"; +"redeem.giftcard.placeholder" = "Pincode cadeaubon"; + +"plan.monthly.title" = "Maandelijks"; +"plan.yearly.title" = "Jaarlijks"; +"plan.yearly.detail_format" = "%@%@ per jaar"; +"plan.price_format" = "%@/ma"; +"plan.best_value" = "Beste waarde"; +"plan.accessibility.per_month" = "per maand"; + +"restore.title" = "Aankoop herstellen"; +"restore.subtitle" = "Als u een abonnement via deze app heeft aangeschaft en u heeft uw gegevens niet ontvangen, dan kunt u ze hier opnieuw verzenden. Er worden geen kosten in rekening gebracht tijdens dit proces."; +"restore.email.placeholder" = "E-mailadres"; +"restore.submit" = "BEVESTIGEN"; + +"iap.error.message.unavailable" = "De Apple-servers zijn momenteel niet beschikbaar. Probeer het later opnieuw."; +"iap.error.title" = "Fout"; + +"agreement.trials.title" = "Algemene voorwaarden gratis proefabonnementen"; +"agreement.trials.message" = "De betaling wordt bij de bevestiging van uw aankoop via uw Apple ID-account in rekening gebracht. Het abonnement wordt automatisch verlengd, tenzij het ten minste 24 uur voor het einde van de huidige periode wordt geannuleerd. De verlenging van uw account wordt binnen 24 uur voor het einde van de huidige periode in rekening gebracht. U kunt uw abonnementen beheren en annuleren door na de aankoop naar uw accountinstellingen in de App Store te gaan.\n\nBepaalde betaalde abonnementen kunnen een gratis proefabonnement aanbieden voordat er kosten in rekening worden gebracht. Als u zich wilt afmelden voor een betaald abonnement voordat we kosten in rekening brengen, moet u het abonnement ten minste 24 uur voor het einde van de gratis proefperiode annuleren.\n\nGratis proefabonnementen zijn alleen beschikbaar voor nieuwe gebruikers. Als u zich aanmeldt voor een aanvullend gratis proefabonnement worden onmiddellijk de standaard abonnementskosten in rekening gebracht.\n\nWij behouden ons het recht voor om uw gratis proefabonnement te allen tijde in te trekken.\n\nEen eventueel ongebruikt deel van uw gratis proefperiode vervalt bij aankoop van een abonnement.\n\nAls u zich aanmeldt, gaat u akkoord met deze algemene voorwaarden."; +"agreement.message" = "Na de gratis proefperiode van 7 dagen wordt het abonnement automatisch verlengd voor %@, tenzij u het ten minste 24 uur voor het einde van de proefperiode annuleert. De kosten voor de verlenging worden binnen 24 uur voor het einde van de proefperiode via uw Apple ID-account in rekening gebracht. U kunt uw abonnementen beheren en annuleren door na de aankoop naar uw accountinstellingen in de App Store te gaan. De proefperiode van 7 dagen is beperkt tot één proefperiode van 7 dagen per gebruiker. Een eventueel ongebruikt deel van uw gratis proefperiode vervalt bij aankoop van een abonnement. Alle prijzen zijn inclusief lokale omzetbelasting, indien van toepassing.\n\nAls u zich aanmeldt, gaat u akkoord met de $1 en het $2."; +"agreement.trials.yearly.plan" = "jaar"; +"agreement.trials.monthly.plan" = "maand"; + +"agreement.message.tos" = "Servicevoorwaarden"; +"agreement.message.privacy" = "Privacybeleid"; + +"getstarted.buttons.buyaccount" = "Account kopen"; + +"gdpr.collect.data.title" = "Persoonlijke informatie die we verzamelen"; +"gdpr.collect.data.description" = "E-mailadres voor accountbeheer en bescherming tegen misbruik."; +"gdpr.usage.data.title" = "Gebruik van de persoonlijke informatie die we verzamelen"; +"gdpr.usage.data.description" = "E-mailadres wordt alleen gebruikt voor het verzenden van abonnementsinformatie, betalingsbevestigingen, correspondentie met klanten en promotionele aanbiedingen van Private Internet Access."; +"gdpr.accept.button.title" = "Akkoord en doorgaan"; + +"update.account.email.error" = "Kan accountmail niet aanpassen"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings new file mode 100644 index 000000000..9922f65c3 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Potwierdź rejestrację"; +"in_progress.message" = "Potwierdzamy zakup w naszym systemie. Poczekaj spokojnie, bo to może trochę potrwać."; +"in_progress.redeem.message" = "Potwierdzamy Twój PIN karty w naszym systemie, TO może chwilę potrwać, więc prosimy o cierpliwość."; + +"success.title" = "Zakup zakończony"; +"success.message_format" = "Dziękujemy za rejestrację. Przesłaliśmy Twoją nazwę użytkownika i hasło na Twój adres e-mail: %@"; +"success.redeem.title" = "Karta została wymieniona"; +"success.redeem.message" = "Wkrótce otrzymasz e-mail z nazwą użytkownika i hasłem.\n\nTwoje dane do logowania"; +"success.username.caption" = "Nazwa użytkownika"; +"success.password.caption" = "Hasło"; +"success.submit" = "Rozpocznij"; + +"failure.vc_title" = "Rejestracja nie powiodła się"; +"failure.title" = "Błąd tworzenia konta"; +"failure.message" = "Obecnie nie możemy utworzyć konta. Spróbuj ponownie później."; +"failure.purchase.sandbox.message" = "Wybrana subskrypcja na piaskownicę (środowisko testowe) nie jest dostępna w produkcji."; +"failure.redeem.invalid.title" = "Nieprawidłowy PIN karty"; +"failure.redeem.invalid.message" = "Wygląda na to, ze wpisałeś nieprawidłowy PIN karty. Spróbuj ponownie."; +"failure.redeem.claimed.title" = "Karta już użyta"; +"failure.redeem.claimed.message" = "Wygląda na to, że ta karta została użyta na innym koncie. Możesz spróbować wpisać inny PIN."; +"failure.submit" = "WSTECZ"; + +"unreachable.vc_title" = "Błąd"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Nie znaleziono połączenia z internetem. Potwierdź, że masz połączenie z internetem i naciśnij „Spróbuj ponownie” poniżej..\n\nMożesz wrócić do aplikacji później, aby dokończyć proces."; +"unreachable.submit" = "SPRÓBUJ PONOWNIE"; + +"purchase.uncredited.alert.message" = "Masz nieuznane transakcje. Chcesz odzyskać dane swojego konta?"; +"purchase.uncredited.alert.button.cancel" = "Anuluj"; +"purchase.uncredited.alert.button.recover" = "Odzyskaj konto"; + +"purchase.trials.intro" = "Zacznij 7-dniowy bezpłatny okres próbny"; +"purchase.trials.price.after" = "Potem %@"; +"purchase.trials.money.back" = "30-dniowa gwarancja zwrotu pieniędzy"; +"purchase.trials.1year.protection" = "1 rok ochrony prywatności i tożsamości"; +"purchase.trials.anonymous" = "Przeglądaj sieć anonimowa i ukryj swoje IP"; +"purchase.trials.devices" = "Obsługa 10 urządzeń jednocześnie"; +"purchase.trials.devices.description" = "Ochrona na maksymalnie 10 urządzeniach jednocześnie."; +"purchase.trials.region" = "Łatwo połączysz się z dowolnym regionem"; +"purchase.trials.servers" = "Ponad 3300 serwerów w 32 krajach"; +"purchase.trials.start" = "Rozpocznij subskrypcję"; +"purchase.trials.all.plans" = "Sprawdź wszystkie dostępne plany"; + +"purchase.subscribe.now" = "Subskrybuj teraz"; + +// WALKTHROUGH + +"walkthrough.action.next" = "DALEJ"; +"walkthrough.action.done" = "GOTOWE"; +"walkthrough.action.skip" = "POMIŃ"; + +"walkthrough.page.1.title" = "Obsługa 10 urządzeń jednocześnie"; +"walkthrough.page.1.description" = "Ochrona na maksymalnie 10 urządzeniach jednocześnie."; +"walkthrough.page.2.title" = "Łatwo połączysz się z dowolnym regionem"; +"walkthrough.page.2.description" = "Dzięki serwerom na całym świecie zawsze jesteś pod ochroną."; +"walkthrough.page.3.title" = "Unikaj reklam"; +"walkthrough.page.3.description" = "Włączenie naszej Blokady zawartości chroni Cię przed wyświetlaniem reklam w Safari."; + +"share.data.buttons.accept" = "Akceptuj"; +"share.data.buttons.noThanks" = "Nie, dziękuję"; +"share.data.buttons.readMore" = "Dowiedz się więcej"; +"share.data.text.title" = "Prosimy o pomoc w ulepszeniu naszych usług"; +"share.data.text.description" = "Aby pomóc nam zapewnić najlepszą wydajność naszych usług, możesz anonimowo udostępniać nam swoje statystyki połączeń. Raporty te nie zawierają żadnych informacji umożliwiających identyfikację osób."; +"share.data.text.footer" = "Zawsze możesz to kontrolować w swoich ustawieniach"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings new file mode 100644 index 000000000..fccbc42bf --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Wersja %@ (%@)"; +"global.close" = "Zamknij"; +"global.ok" = "OK"; +"global.cancel" = "Anuluj"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings new file mode 100644 index 000000000..1af0054e2 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Zaloguj się na konto"; +"login.username.placeholder" = "Nazwa użytkownika (p1234567)"; +"login.password.placeholder" = "Hasło"; +"login.submit" = "ZALOGUJ"; +"login.restore.button" = "Nie dostałeś(-aś) Danych swojego konta?"; +"login.error.title" = "Zaloguj"; +"login.error.validation" = "Musisz podać nazwę użytkownika i hasło."; +"login.error.unauthorized" = "Twoja nazwa użytkownika i hasło są nieprawidłowe."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Zaloguj się, używając pokwitowania zakupu"; +"login.magic.link.title" = "Zaloguj się, używając sekretnego linku z e-maila"; +"login.magic.link.response" = "Link do logowania wysłaliśmy e-mailem,"; +"login.magic.link.send" = "Wyślij link"; +"login.magic.link.invalid.email" = "Nieprawidłowy e-mail. Spróbuj ponownie"; + +"purchase.title" = "Wybierz plan VPN"; +"purchase.subtitle" = "30-dniowej gwarancji zwrotu pieniędzy"; +"purchase.email.placeholder" = "Adres e-mail"; +"purchase.continue" = "Kontynuuj"; +"purchase.login.footer" = "Masz już konto?"; +"purchase.login.button" = "Zaloguj"; +"purchase.error.title" = "Zakup"; +"purchase.error.validation" = "Musisz podać adres e-mail."; +"purchase.error.connectivity.title" = "Błąd połączenia"; +"purchase.error.connectivity.description" = "Nie można połączyć z Private Internet Access. Może to być spowodowane słabym połączeniem z internetem lub nasza usługa może być zablokowana w Twoim kraju."; +"purchase.confirm.form.email" = "Podaj swój adres e-mail"; +"purchase.confirm.plan" = "Kupujesz abonament %@"; +"purchase.email.why" = "Twój e-mail jest nam potrzebny do przesłania Ci nazwy użytkownika i hasła,"; +"purchase.submit" = "Wyślij"; +"purchase.or" = "lub"; + +"upgrade.header" = "Witaj ponownie!"; +"upgrade.title" = "Aby korzystać z Private Internet Access, musisz odnowić swoją subskrypcję."; +"upgrade.renew.now" = "Odnów teraz"; + + + +"redeem.title" = "Wykorzystaj kartę podarunkową"; +"redeem.subtitle" = "Wpisz swój adres e-mail oraz %lu-cyfrowy PIN z karty podarunkowej lub karty próbnej poniżej."; +"redeem.email.placeholder" = "Adres e-mail"; +"redeem.submit" = "PRZEŚLIJ"; +"redeem.error.title" = "Wykorzystaj"; +"redeem.error.code" = "Kod musi składać się z %lu znaków numerycznych."; +"redeem.error.allfields" = "Podaj swój adres r-mail i PIN karty"; +"redeem.accessibility.back" = "Wstecz"; +"redeem.giftcard.placeholder" = "PIN karty upominkowej"; + +"plan.monthly.title" = "Miesięcznie"; +"plan.yearly.title" = "Rocznie"; +"plan.yearly.detail_format" = "%@%@ rocznie"; +"plan.price_format" = "%@/msc."; +"plan.best_value" = "Najlepsza wartość"; +"plan.accessibility.per_month" = "miesięcznie"; + +"restore.title" = "Przywróć pominięty zakup"; +"restore.subtitle" = "Jeśli kupił(a)ś abonament, korzystając z tej aplikacji, ale nie dostałe(a)ś danych logowania, możesz wysłać je ponownie stąd.\nOpłata nie zostanie za to pobrana za tę czynność"; +"restore.email.placeholder" = "Adres e-mail"; +"restore.submit" = "POTWIERDŹ"; + +"iap.error.message.unavailable" = "Serwery Apple'a są w tej chwili niedostępne. Spróbuj ponownie później."; +"iap.error.title" = "Błąd"; + +"agreement.trials.title" = "Regulamin korzystania z bezpłatnej wersji próbnej"; +"agreement.trials.message" = "Płatność zostanie pobrana z Twojego konta Apple ID z chwilą potwierdzenia zakupu. Subskrypcja odnawia się automatycznie, chyba że zostanie anulowana co najmniej 24 godziny przed końcem bieżącego okresu rozliczeniowego. Opłata za odnowienie subskrypcji zostanie pobrana w ciągu 24 godzin przed końcem bieżącego okresu. Możesz zarządzać subskrypcjami i je anulować, przechodząc do ustawień konta w App Store po dokonaniu zakupu.\n\nCzęść płatnych Subskrypcji może obejmować bezpłatną wersję próbną, z której możesz skorzystać przed naliczeniem opłaty. Jeśli postanowisz zrezygnować z płatnej subskrypcji przed rozpoczęciem naliczania opłat zgodnie z wybraną metodą płatności, anuluj subskrypcję co najmniej 24 godziny przed zakończeniem bezpłatnej wersji próbnej.\n\nBezpłatne wersje próbne są dostępne tylko dla nowych użytkowników i są przyznawane wyłącznie według naszego uznania, a w przypadku próby zarejestrowania w celu uzyskania dodatkowej bezpłatnej wersji próbnej, zostaniesz natychmiast obciążony standardową opłatą subskrypcyjną.\n\nRejestracja oznacza akceptację niniejszego regulaminu."; +"agreement.message" = "Po 7 dniach bezpłatnego okresu próbnego ta subskrypcja odnowi się automatycznie na %@, jeżeli nie zostanie anulowana co najmniej 24 godziny przed końcem okresu próbnego. Twoje konto Apple ID zostanie obciążone opłatą za odnowienie w ciągu 24 godzin przed końcem okresu próbnego. Możesz zarządzać swoimi subskrypcjami i je anulować, wchodząc po zakupie w ustawienia swojego konta w App Store Oferta 7-dniowego okresu próbnego jest ograniczona – każdemu użytkownikowi przysługuje jeden 7-dniowy okres próbny. Każda niewykorzystana część bezpłatnego okresu próbnego, jeśli zostanie zaoferowany, przepada wraz zakupem subskrypcji przez użytkownika. Wszystkie ceny zawierają obowiązujące lokalne podatki obrotowe.\n\nRejestracja oznacza akceptację artykułów. $1 i $2."; +"agreement.trials.yearly.plan" = "rok"; +"agreement.trials.monthly.plan" = "miesiąc"; + +"agreement.message.tos" = "Warunki użytkowania"; +"agreement.message.privacy" = "Zasady ochrony prywatności"; + +"getstarted.buttons.buyaccount" = "Zakup konto"; + +"gdpr.collect.data.title" = "Zbierane dane osobowe"; +"gdpr.collect.data.description" = "Adres e-mail do zarządzania kontem i ochrony przed nadużyciami."; +"gdpr.usage.data.title" = "Sposoby wykorzystania zbieranych przez nas danych osobowych"; +"gdpr.usage.data.description" = "Adres e-mail; używany go do wysyłania informacji o subskrypcji, potwierdzeń płatności, korespondencji z klientami i wysyłania ofert promocyjnych wyłącznie Private Internet Access"; +"gdpr.accept.button.title" = "Zaakceptuj i kontynuuj"; + +"update.account.email.error" = "Nie udało się zmienić adresu e-mail konta"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings new file mode 100644 index 000000000..5bcf7cb9a --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirme o registro"; +"in_progress.message" = "Confirmamos sua compra com o nosso sistema. Isso pode demorar um pouco. Por favor, aguarde."; +"in_progress.redeem.message" = "Estamos confirmando o PIN do seu cartão com o nosso sistema. Isso pode demorar um pouco. Por favor, aguarde."; + +"success.title" = "Compra Concluída"; +"success.message_format" = "Obrigado por se registrar conosco. Nós enviamos o nome de usuário e a senha da sua conta para o seu endereço de e-mail em %@"; +"success.redeem.title" = "Cartão resgatado com sucesso"; +"success.redeem.message" = "Você receberá um e-mail com seu nome de usuário e senha em breve.\n\nSeus dados de login"; +"success.username.caption" = "Nome de usuário"; +"success.password.caption" = "Senha"; +"success.submit" = "Comece Agora"; + +"failure.vc_title" = "Falha ao registrar"; +"failure.title" = "Falha ao Criar Conta"; +"failure.message" = "Não podemos criar uma conta neste momento. Tente novamente mais tarde.\n\nApós a reabertua do aplicativo, uma nova tentativa de criação de conta será realizada."; +"failure.purchase.sandbox.message" = "A assinatura da área restrita selecionada não está disponível em produção."; +"failure.redeem.invalid.title" = "PIN de cartão inválido"; +"failure.redeem.invalid.message" = "Parece que você inseriu um PIN de cartão inválido. Por favor, tente novamente."; +"failure.redeem.claimed.title" = "O cartão já foi resgatado"; +"failure.redeem.claimed.message" = "Parece que este cartão já foi resgatado por outra conta. Você pode tentar usar um PIN diferente."; +"failure.submit" = "VOLTAR"; + +"unreachable.vc_title" = "Erro"; +"unreachable.title" = "Ops!"; +"unreachable.message" = "Nenhuma conexão com a Internet encontrada. Confirme que você possui uma conexão com a Internet e pressione Tentar Novamente abaixo.\n\nVocê pode retornar ao aplicativo mais tarde para finalizar o processo."; +"unreachable.submit" = "TENTAR NOVAMENTE"; + +"purchase.uncredited.alert.message" = "Você tem transações não creditadas. Deseja recuperar os detalhes da sua conta?"; +"purchase.uncredited.alert.button.cancel" = "Cancelar"; +"purchase.uncredited.alert.button.recover" = "Recuperar conta"; + +"purchase.trials.intro" = "Comece sua avaliação gratuita de 7 dias"; +"purchase.trials.price.after" = "Em seguida, %@"; +"purchase.trials.money.back" = "Garantia do dinheiro de volta em até 30 dias"; +"purchase.trials.1year.protection" = "1 ano de proteção de privacidade e identidade"; +"purchase.trials.anonymous" = "Navegue anonimamente e oculte seu IP."; +"purchase.trials.devices" = "Suporte para 10 dispositivos ao mesmo tempo"; +"purchase.trials.devices.description" = "Proteja-se em até 10 dispositivos ao mesmo tempo."; +"purchase.trials.region" = "Conecte-se a qualquer região facilmente"; +"purchase.trials.servers" = "Mais de 3.300 servidores em 32 países"; +"purchase.trials.start" = "Iniciar assinatura"; +"purchase.trials.all.plans" = "Veja todos os planos disponíveis"; + +"purchase.subscribe.now" = "Assine agora"; + +// WALKTHROUGH + +"walkthrough.action.next" = "AVANÇAR"; +"walkthrough.action.done" = "CONCLUÍDO"; +"walkthrough.action.skip" = "PULAR"; + +"walkthrough.page.1.title" = "Suporte para 10 dispositivos ao mesmo tempo"; +"walkthrough.page.1.description" = "Proteja-se em até 10 dispositivos ao mesmo tempo."; +"walkthrough.page.2.title" = "Conecte-se a qualquer região facilmente"; +"walkthrough.page.2.description" = "Com servidores ao redor do mundo, você está sempre protegido."; +"walkthrough.page.3.title" = "Proteja-se contra propagandas"; +"walkthrough.page.3.description" = "A ativação do nosso Bloqueador de Conteúdo impede que anúncios sejam exibidos no Safari."; + +"share.data.buttons.accept" = "Aceitar"; +"share.data.buttons.noThanks" = "Não, obrigado"; +"share.data.buttons.readMore" = "Leia mais"; +"share.data.text.title" = "Ajude-nos a melhorar nosso serviço"; +"share.data.text.description" = "Para nos ajudar a garantir o desempenho da conexão de nosso serviço, você pode compartilhar anonimamente as estatísticas da sua conexão conosco. Esses relatórios não incluem nenhuma informação de identificação pessoal."; +"share.data.text.footer" = "Você sempre poderá controlar isso em suas configurações"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings new file mode 100644 index 000000000..32e6d7e28 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versão %@ (%@)"; +"global.close" = "Fechar"; +"global.ok" = "OK"; +"global.cancel" = "Cancelar"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings new file mode 100644 index 000000000..7ed6d1e85 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Entre na sua conta"; +"login.username.placeholder" = "Nome de usuário (p1234567)"; +"login.password.placeholder" = "Senha"; +"login.submit" = "ENTRAR"; +"login.restore.button" = "Não recebeu detalhes da conta?"; +"login.error.title" = "Entrar"; +"login.error.validation" = "Você deve inserir um nome de usuário e senha."; +"login.error.unauthorized" = "Seu nome de usuário ou senha está incorreto."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Faça login usando o recibo de compra"; +"login.magic.link.title" = "Faça login usando o link mágico enviado por e-mail"; +"login.magic.link.response" = "Veja se você recebeu por e-mail um link para fazer login."; +"login.magic.link.send" = "Enviar link"; +"login.magic.link.invalid.email" = "E-mail inválido. Tente novamente."; + +"purchase.title" = "Selecione um plano de VPN"; +"purchase.subtitle" = "Garantia do dinheiro de volta em até 30 dias"; +"purchase.email.placeholder" = "Endereço de e-mail"; +"purchase.continue" = "Continuar"; +"purchase.login.footer" = "Já tem uma conta?"; +"purchase.login.button" = "Faça login"; +"purchase.error.title" = "Comprar"; +"purchase.error.validation" = "Você precisa inserir um endereço de e-mail."; +"purchase.error.connectivity.title" = "Falha na conexão"; +"purchase.error.connectivity.description" = "Não conseguimos acessar o Private Internet Access. Isso pode ser devido a uma conexão de internet fraca ou o nosso serviço está bloqueado em seu país."; +"purchase.confirm.form.email" = "Insira seu endereço de e-mail"; +"purchase.confirm.plan" = "Você está adquirindo o plano %@"; +"purchase.email.why" = "Precisamos do seu e-mail para enviarmos seu nome de usuário e senha."; +"purchase.submit" = "Enviar"; +"purchase.or" = "ou"; + +"upgrade.header" = "Seja bem-vindo(a)!"; +"upgrade.title" = "Para usar a Private Internet Access, você precisará renovar sua assinatura."; +"upgrade.renew.now" = "Renovar agora"; + + + +"redeem.title" = "Resgatar cartão-presente"; +"redeem.subtitle" = "Digite o seu endereço de e-mail e o PIN de %lu dígitos do seu cartão-presente ou cartão de teste abaixo."; +"redeem.email.placeholder" = "Endereço de e-mail"; +"redeem.submit" = "ENVIAR"; +"redeem.error.title" = "Resgatar"; +"redeem.error.code" = "O código precisa ter %lu dígitos numéricos."; +"redeem.error.allfields" = "Digite o seu e-mail e PIN do cartão."; +"redeem.accessibility.back" = "Voltar"; +"redeem.giftcard.placeholder" = "PIN do cartão-presente"; + +"plan.monthly.title" = "Mensal"; +"plan.yearly.title" = "Anual"; +"plan.yearly.detail_format" = "%@%@ por ano"; +"plan.price_format" = "%@/mês"; +"plan.best_value" = "Melhor valor"; +"plan.accessibility.per_month" = "por mês"; + +"restore.title" = "Restaurar compra não creditada"; +"restore.subtitle" = "Se você adquiriu um plano por este aplicativo e não recebeu as suas credenciais, você pode enviá-las novamente por aqui. Você não será cobrado durante esse processo."; +"restore.email.placeholder" = "Endereço de e-mail"; +"restore.submit" = "CONFIRMAR"; + +"iap.error.message.unavailable" = "Servidores da Apple indisponíveis no momento. Tente novamente mais tarde."; +"iap.error.title" = "Erro"; + +"agreement.trials.title" = "Termos e condições das avaliações gratuitas"; +"agreement.trials.message" = "O pagamento será cobrado na sua conta do ID Apple no ato da confirmação da compra. A assinatura será renovada automaticamente, a não ser que ela seja cancelada, pelo menos, 24 horas antes do fim do período atual. O valor da renovação será debitado na sua conta em até 24 horas antes do término do período da atual. Você pode gerenciar e cancelar suas assinaturas nos ajustes da conta na App Store após a compra.\n\nCertas assinaturas pagas podem oferecer uma avaliação gratuita antes da cobrança do pagamento. Se você decidir cancelar uma Assinatura Paga antes de começarmos a cobrar por ela, cancele-a, pelo menos, 24 horas antes do término da avaliação gratuita.\n\nAs avaliações gratuitas estão disponíveis apenas para novos usuários, e são a nosso critério. Se tentar se registrar para uma avaliação gratuita adicional, você será cobrado imediatamente com a Taxa de Assinatura padrão.\n\nReservamo-nos o direito de revogar sua avaliação gratuita a qualquer momento.\n\nQualquer parte não utilizada do período da sua avaliação gratuita será perdida após a compra de uma assinatura.\n\nO registro constitui da aceitação dos termos e condições."; +"agreement.message" = "Após os 7 dias da avaliação gratuita, a assinatura será renovada automaticamente por %@, a não ser que ela seja cancelada, pelo menos, 24 horas antes do término do período de avaliação. O valor da renovação será debitado da conta do seu ID Apple em até 24 horas antes do término do período de avaliação. Você pode gerenciar e cancelar suas assinaturas nos ajustes da conta da App Store após a compra. A oferta de avaliação de 7 dias é limitada a uma oferta de avaliação de 7 dias por usuário. Qualquer parte não utilizada do período de avaliação gratuita, se oferecida, será perdida após a aquisição de uma assinatura. Todos os preços incluem impostos de vendas locais aplicáveis.\n\nO registro constitui da aceitação dos $1 e da $2."; +"agreement.trials.yearly.plan" = "ano"; +"agreement.trials.monthly.plan" = "mês"; + +"agreement.message.tos" = "Termos de Serviço"; +"agreement.message.privacy" = "Política de Privacidade"; + +"getstarted.buttons.buyaccount" = "Comprar conta"; + +"gdpr.collect.data.title" = "Informações pessoais que coletamos"; +"gdpr.collect.data.description" = "Endereço de e-mail para gerenciamento de conta e proteção contra abuso."; +"gdpr.usage.data.title" = "Uso de informações pessoais coletadas por nós"; +"gdpr.usage.data.description" = "O endereço de e-mail é utilizado apenas para enviar informação de assinatura, confirmações de pagamento, correspondência com clientes e ofertas promocionais do Private Internet Access."; +"gdpr.accept.button.title" = "Concordar e continuar"; + +"update.account.email.error" = "Falha ao modificar o e-mail da conta"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings new file mode 100644 index 000000000..9f032f794 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Подтверждение регистрации"; +"in_progress.message" = "Мы проверяем вашу покупку в системе. На это может понадобиться время, так что оставайтесь с нами."; +"in_progress.redeem.message" = "Мы подтверждаем ваш PIN-код в системе. Это займет какое-то время, подождите немного."; + +"success.title" = "Покупка завершена"; +"success.message_format" = "Спасибо за регистрацию. Мы отправили имя пользователя и пароль на адрес электронной почты %@"; +"success.redeem.title" = "Карта успешно использована"; +"success.redeem.message" = "Также вы получите эл. письмо с именем пользователя и паролем.\n\nВаши учетные данные"; +"success.username.caption" = "Имя пользователя"; +"success.password.caption" = "Пароль"; +"success.submit" = "Начать"; + +"failure.vc_title" = "Ошибка регистрации"; +"failure.title" = "Сбой создания учетной записи"; +"failure.message" = "Нам не удалось создать учетную запись. Повторите попытку позже.\nПри повторном открытии приложения создание учетной записи будет возобновлено."; +"failure.purchase.sandbox.message" = "Выбранная подписка на «песочницу» недоступна в производственной среде."; +"failure.redeem.invalid.title" = "Неверный PIN-код карты"; +"failure.redeem.invalid.message" = "Похоже, вы ввели неверный PIN-код карты. Попробуйте еще раз."; +"failure.redeem.claimed.title" = "Карта уже использована"; +"failure.redeem.claimed.message" = "Похоже, эту карту уже использовали с другой учетной записи. Попробуйте ввести другой PIN."; +"failure.submit" = "ВОЗВРАТ"; + +"unreachable.vc_title" = "Ошибка"; +"unreachable.title" = "Ой!"; +"unreachable.message" = "Интернет-соединение не найдено. Пожалуйста, убедитесь, что у вас есть подключение к Интернету, и повторите попытку позже.\n\nМожно вернуться в приложение позже и завершить процесс."; +"unreachable.submit" = "ПОВТОРИТЬ"; + +"purchase.uncredited.alert.message" = "У вас есть непроведенные транзакции. Хотите восстановить данные своей учетной записи?"; +"purchase.uncredited.alert.button.cancel" = "Отмена"; +"purchase.uncredited.alert.button.recover" = "Восстановить учетную запись"; + +"purchase.trials.intro" = "Начните 7-дневную бесплатную пробу"; +"purchase.trials.price.after" = "После этого %@"; +"purchase.trials.money.back" = "30-дневная гарантия возврата денег"; +"purchase.trials.1year.protection" = "1 год защиты конфиденциальности и личных данных"; +"purchase.trials.anonymous" = "Пользуйтесь Интернетом анонимно и скрывайте свой IP-адрес."; +"purchase.trials.devices" = "Поддержка сразу 10 устройств"; +"purchase.trials.devices.description" = "Защищайте себя на нескольких устройствах одновременно (до 10)."; +"purchase.trials.region" = "Простое подключение к любому региону"; +"purchase.trials.servers" = "Более 3300 серверов в 32 странах"; +"purchase.trials.start" = "Запустить подписку."; +"purchase.trials.all.plans" = "Смотреть все доступные планы"; + +"purchase.subscribe.now" = "Подписаться"; + +// WALKTHROUGH + +"walkthrough.action.next" = "ДАЛЕЕ"; +"walkthrough.action.done" = "ГОТОВО"; +"walkthrough.action.skip" = "ПРОПУСК"; + +"walkthrough.page.1.title" = "Поддержка 10 устройств одновременно"; +"walkthrough.page.1.description" = "Защищайте себя на нескольких устройствах одновременно (до 10)."; +"walkthrough.page.2.title" = "Простое подключение к любому региону"; +"walkthrough.page.2.description" = "У нас есть серверы по всему миру, так что вы всегда будете под защитой."; +"walkthrough.page.3.title" = "Защита от рекламы"; +"walkthrough.page.3.description" = "Активация нашего правила блокирования контента препятствует отображению рекламы в Safari."; + +"share.data.buttons.accept" = "Принять"; +"share.data.buttons.noThanks" = "Спасибо, не надо"; +"share.data.buttons.readMore" = "Подробнее"; +"share.data.text.title" = "Помогите нам сделать нашу службу еще лучше"; +"share.data.text.description" = "Вы можете анонимно делиться с нами своей статистикой соединения, чтобы помочь нам обеспечить производительность подключения нашей службы. Эти отчеты не включают какую-либо личную информацию."; +"share.data.text.footer" = "Вы всегда можете управлять этим параметром через настройки"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings new file mode 100644 index 000000000..2d1416365 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Версия %@ (%@)"; +"global.close" = "Закрыть"; +"global.ok" = "ОК"; +"global.cancel" = "Отмена"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings new file mode 100644 index 000000000..cd0684978 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Войдите в свою учетную запсь"; +"login.username.placeholder" = "Имя пользователя (p1234567)"; +"login.password.placeholder" = "Пароль"; +"login.submit" = "ВХОД"; +"login.restore.button" = "Не получили данные учетной записи?"; +"login.error.title" = "Войти"; +"login.error.validation" = "Нужно ввести имя пользователя и пароль."; +"login.error.unauthorized" = "Неправильное имя пользователя или пароль."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Выполните вход по квитанции о покупке"; +"login.magic.link.title" = "Войти через волшебную ссылку из письма"; +"login.magic.link.response" = "Поищите ссылку для входа в письме."; +"login.magic.link.send" = "Отправить ссылку"; +"login.magic.link.invalid.email" = "Недействительный эл. адрес. Повторите попытку."; + +"purchase.title" = "Выберите план VPN"; +"purchase.subtitle" = "30-дневная гарантия возврата денег"; +"purchase.email.placeholder" = "Адрес эл. почты"; +"purchase.continue" = "Продолжить"; +"purchase.login.footer" = "Уже есть учетная запись?"; +"purchase.login.button" = "Вход"; +"purchase.error.title" = "Купить"; +"purchase.error.validation" = "Укажите адрес эл. почты."; +"purchase.error.connectivity.title" = "Ошибка подключения"; +"purchase.error.connectivity.description" = "Не удалось подключиться к Private Internet Access. Это может быть из-за плохого качества соединения с Интернетом, или наша служба заблокирована в вашей стране."; +"purchase.confirm.form.email" = "Введите свой адрес эл. почты"; +"purchase.confirm.plan" = "Вы приобретаете план «%@»"; +"purchase.email.why" = "Нам нужен ваш электронный адрес, чтобы мы могли прислать вам имя пользователя и пароль."; +"purchase.submit" = "Отправить"; +"purchase.or" = "или"; + +"upgrade.header" = "С возвращением!"; +"upgrade.title" = "Чтобы пользоваться Private Internet Access, вам необходимо продлить подписку."; +"upgrade.renew.now" = "Продлить"; + + + +"redeem.title" = "Исп-ть подарочную карту"; +"redeem.subtitle" = "Введите свой адрес эл. почты и %lu-зн. PIN-код с подарочной или триальной карты."; +"redeem.email.placeholder" = "Адрес эл. почты"; +"redeem.submit" = "ОТПРАВИТЬ"; +"redeem.error.title" = "Использовать"; +"redeem.error.code" = "В коде должно быть %lu цифр(ы)."; +"redeem.error.allfields" = "Введите свой эл. адрес и PIN-код карты"; +"redeem.accessibility.back" = "Назад"; +"redeem.giftcard.placeholder" = "PIN-код подарочной карты"; + +"plan.monthly.title" = "Ежемесячно"; +"plan.yearly.title" = "Ежегодно"; +"plan.yearly.detail_format" = "%@%@ в год"; +"plan.price_format" = "%@/мес."; +"plan.best_value" = "Максимальная выгода"; +"plan.accessibility.per_month" = "в месяц"; + +"restore.title" = "Восстановить непроведенную покупку"; +"restore.subtitle" = "Если вы купили план через это приложение и не получили учетных данных, вы можете повторно отправить их отсюда. За эту процедуру не взимается плата."; +"restore.email.placeholder" = "Адрес электронной почты"; +"restore.submit" = "ПОДТВЕРДИТЬ"; + +"iap.error.message.unavailable" = "Серверы Apple временно недоступны. Повторите попытку позже."; +"iap.error.title" = "Ошибка"; + +"agreement.trials.title" = "Положения и условия бесплатного пробного пользования"; +"agreement.trials.message" = "Платеж списывается со счета вашего Apple ID при подтверждении покупки. Подписка продлевается автоматически, если не отменить ее по меньшей мере за 24 часа до окончания текущего периода. Плата за продление подписки будет списана со счета вашей учетной записи в течение 24 часов до окончания текущего периода. Для управления подписками, в том числе их отмены, после покупки перейдите в настройки учетной записи в App Store.\n\nНекоторые платные подписки могут предлагать бесплатное пробное пользование перед тем, как списывать средства с использованием указанного вами способа оплаты. Если вы решите отменить платную подписку до того, как мы начнем списывать средства с использованием указанного вами способа оплаты, сделайте это по меньшей мере за 24 часа до окончания бесплатного пробного периода.\n\nБесплатное пробное пользование доступно только для новых пользователей и предлагается по нашему единоличному усмотрению, и если вы попытаетесь зарегистрироваться для участия в дополнительном бесплатном пробном пользовании, с вас будет незамедлительно списана стандартная стоимость подписки.\n\nМы оставляем за собой право в любое время прервать ваше бесплатное пробное пользование.\n\nНеиспользованная часть бесплатного пробного периода сгорает после приобретения подписки.\n\nЗарегистрировавшись, вы тем самым принимаете настоящие положения и условия."; +"agreement.message" = "После завершения 7-дневного бесплатного пробного периода подписка автоматически продлевается на %@, если не отменить ее по меньшей мере за 24 часа до окончания текущего периода. Плата за продление подписки будет списана со счета вашей учетной записи в течение 24 часов до окончания текущего периода. Для управления подписками, в том числе их отмены, после покупки перейдите в настройки учетной записи в App Store. 7-дневное пробное пользование предлагается каждому пользователю только 1 раз. Неиспользованная часть бесплатного пробного периода сгорает после приобретения подписки. Цена указывается с учетом местных налогов на продажу.\n\nРегистрируясь, вы тем самым принимаете списание с вашего счета сумм в $1 и $2 доллара США."; +"agreement.trials.yearly.plan" = "год"; +"agreement.trials.monthly.plan" = "месяц"; + +"agreement.message.tos" = "Условия использования"; +"agreement.message.privacy" = "Политика конфиденциальности"; + +"getstarted.buttons.buyaccount" = "Приобрести учетную запись"; + +"gdpr.collect.data.title" = "Личная информация, которую мы собираем"; +"gdpr.collect.data.description" = "Адрес эл. почты используется в целях управления учетной записью и защиты от злоупотреблений."; +"gdpr.usage.data.title" = "Использование собираемой нами личной информации"; +"gdpr.usage.data.description" = "Адрес эл. почты используется исключительно для отправки информации о подписке, подтверждений оплаты, переписки с пользователем и отправки акционных предложений Private Internet Access."; +"gdpr.accept.button.title" = "Принять и продолжить"; + +"update.account.email.error" = "Не удалось изменить эл. адрес учетной записи"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings new file mode 100644 index 000000000..520a4ea39 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "ยืนยันการสมัคร"; +"in_progress.message" = "เรากำลังยืนยันการซื้อของคุณกับระบบของเรา กรุณารอสักครู่"; +"in_progress.redeem.message" = "เรากำลังยืนยัน PIN การ์ดของคุณกับระบบของเรา กรุณารอสักครู่"; + +"success.title" = "ซื้อสำเร็จ"; +"success.message_format" = "ขอบคุณที่สมัครสมาชิกกับเรา เราได้ส่งชื่อผู้ใช้และรหัสผ่านไปยังอีเมลของคุณแล้วที่ %@"; +"success.redeem.title" = "คืนบัตรเสร็จสมบูรณ์!"; +"success.redeem.message" = "คุณจะได้รับอีเมลพร้อมชื่อผู้ใช้และรหัสผ่านในไม่ช้า\n\nข้อมูลการล็อกอิน"; +"success.username.caption" = "ชื่อผู้ใช้"; +"success.password.caption" = "รหัสผ่าน"; +"success.submit" = "เริ่มใช้งาน"; + +"failure.vc_title" = "การสมัครล้มเหลว"; +"failure.title" = "สร้างบัญชีผู้ใช้ไม่สำเร็จ"; +"failure.message" = "เราไม่สามารถสร้างบัญชีได้ในขณะนี้ กรุณาลองใหม่อีกครั้งภายหลัง การปิดเปิดแอปใหม่จะเป็นการพยายามสร้างบัญชีใหม่"; +"failure.purchase.sandbox.message" = "ไม่มีระบบสมาชิก Sandbox ที่คุณเลือกอยู่ในการผลิต"; +"failure.redeem.invalid.title" = "PIN การ์ดไม่ถูกต้อง"; +"failure.redeem.invalid.message" = "ดูเหมือนว่าคุณใส่ PIN การ์ดไม่ถูกต้อง กรุณาลองใหม่"; +"failure.redeem.claimed.title" = "บัตรมีการใช้สิทธิ์แล้ว"; +"failure.redeem.claimed.message" = "ดูเหมือนว่าบัตรนี้มีการใช้สิทธิ์แล้วโดยบัญชีอื่น กรุณาลองใส่ PIN อื่น"; +"failure.submit" = "ย้อนกลับ"; + +"unreachable.vc_title" = "ข้อผิดพลาด"; +"unreachable.title" = "อุ๊ปส์!"; +"unreachable.message" = "ไม่พบการเชื่อมต่ออินเทอร์เน็ต กรุณายืนยันว่าคุณมีการเชื่อมต่ออินเทอร์เน็ตแล้วกดลองอีกครั้งด้านล่างนี้\n\nคุณสามารถกลับมาใหม่ในภายหลังเพื่อดำเนินการต่อให้เสร็จ"; +"unreachable.submit" = "ลองใหม่"; + +"purchase.uncredited.alert.message" = "คุณได้ยกเลิกการทำธุรกรรมแล้ว คุณต้องการกู้คืนรายละเอียดบัญชีหรือไม่"; +"purchase.uncredited.alert.button.cancel" = "ยกเลิก"; +"purchase.uncredited.alert.button.recover" = "กู้คืนบัญชี"; + +"purchase.trials.intro" = "เริ่มทดลองใช้ฟรี 7 วัน"; +"purchase.trials.price.after" = "จากนั้น %@"; +"purchase.trials.money.back" = "รับประกันการคืนเงินภายใน 30 วัน"; +"purchase.trials.1year.protection" = "การป้องกันข้อมูลประจำตัวและความเป็นส่วนตัว 1 ปี"; +"purchase.trials.anonymous" = "เรียกดูโดยไม่ระบุชื่อและซ่อน ip ของคุณ"; +"purchase.trials.devices" = "รับรองอุปกรณ์ 10 เครื่องในเวลาเดียวกัน"; +"purchase.trials.devices.description" = "ปกป้องตัวคุณบนอุปกรณ์ถึง 10 เครื่องในเวลาเดียวกัน"; +"purchase.trials.region" = "เชื่อมต่อไปยังภูมิภาคใดก็ตามได้อย่างง่ายดาย"; +"purchase.trials.servers" = "กว่า 3300 เซิร์ฟเวอร์ใน 32 ประเทศ"; +"purchase.trials.start" = "เริ่มการเป็นสมาชิก"; +"purchase.trials.all.plans" = "ดูแผนที่มีทั้งหมด"; + +"purchase.subscribe.now" = "สมัครสมาชิกตอนนี้"; + +// WALKTHROUGH + +"walkthrough.action.next" = "ถัดไป"; +"walkthrough.action.done" = "เสร็จสิ้น"; +"walkthrough.action.skip" = "ข้าม"; + +"walkthrough.page.1.title" = "รับรองอุปกรณ์ 10 เครื่องในคราวเดียว"; +"walkthrough.page.1.description" = "ปกป้องตัวคุณบนอุปกรณ์ถึง 10 เครื่องในเวลาเดียวกัน"; +"walkthrough.page.2.title" = "เชื่อมต่อไปยังภูมิภาคใดก็ตามได้อย่างง่ายดาย"; +"walkthrough.page.2.description" = "ด้วยเซิร์ฟเวอร์ที่มีอยู่ทั่วโลก คุณจะได้รับความคุ้มครองตลอดเวลา"; +"walkthrough.page.3.title" = "ปกป้องตัวคุณจากโฆษณา"; +"walkthrough.page.3.description" = "การเปิดใช้งานตัวปิดกั้นเนื้อหาของเราจะเป็นการป้องกันไม่ให้แสดงโฆษณาใน Safari"; + +"share.data.buttons.accept" = "ยอมรับ"; +"share.data.buttons.noThanks" = "ไม่ล่ะ ขอบคุณ"; +"share.data.buttons.readMore" = "อ่านเพิ่มเติม"; +"share.data.text.title" = "โปรดช่วยเราปรับปรุงบริการของเรา"; +"share.data.text.description" = "เพื่อช่วยให้เรามั่นใจในประสิทธิภาพการเชื่อมต่อของบริการของเรา คุณสามารถแชร์สถิติการเชื่อมต่อของคุณกับเราโดยไม่ระบุชื่อ รายงานเหล่านี้ไม่รวมข้อมูลส่วนบุคคลที่สามารถระบุตัวตนได้"; +"share.data.text.footer" = "คุณสามารถควบคุมสิ่งนี้ได้จากการตั้งค่าของคุณ"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/UI.strings new file mode 100644 index 000000000..3069ecff4 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "เวอร์ชั่น %@ (%@)"; +"global.close" = "ปิด"; +"global.ok" = "ตกลง"; +"global.cancel" = "ยกเลิก"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings new file mode 100644 index 000000000..637de14e0 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "ลงชื่อเข้าใช้บัญชีของคุณ"; +"login.username.placeholder" = "ชื่อผู้ใช้ (p1234567)"; +"login.password.placeholder" = "รหัสผ่าน"; +"login.submit" = "เข้าสู่ระบบ"; +"login.restore.button" = "ยังไม่ได้รับรายละเอียดบัญชีหรือ"; +"login.error.title" = "เข้าสู่ระบบ"; +"login.error.validation" = "คุณต้องกรอกชื่อผู้ใช้และรหัสผ่าน"; +"login.error.unauthorized" = "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "เข้าสู่ระบบโดยใช้ใบเสร็จรับเงิน"; +"login.magic.link.title" = "เข้าสู่ระบบโดยใช้ลิงก์อีเมลวิเศษ"; +"login.magic.link.response" = "โปรดตรวจสอบอีเมลของคุณเพื่อดูลิงค์สำหรับเข้าสู่ระบบ"; +"login.magic.link.send" = "ส่งลิงก์"; +"login.magic.link.invalid.email" = "อีเมลไม่ถูกต้อง กรุณาลองอีกครั้ง"; + +"purchase.title" = "เลือกแผน VPN"; +"purchase.subtitle" = "รับประกันการคืนเงินภายใน 30 วัน"; +"purchase.email.placeholder" = "อีเมลแอดเดรส"; +"purchase.continue" = "ดำเนินการต่อ"; +"purchase.login.footer" = "มีบัญชีแล้วหรือยัง"; +"purchase.login.button" = "ลงชื่อเข้าใช้"; +"purchase.error.title" = "ซื้อ"; +"purchase.error.validation" = "คุณต้องใส่ที่อยู่อีเมล"; +"purchase.error.connectivity.title" = "ความล้มเหลวในการเชื่อมต่อ"; +"purchase.error.connectivity.description" = "เราไม่สามารถเข้าถึง Private Internet Access ซึ่งอาจเป็นเพราะอินเทอร์เน็ตไม่เสถียรหรือบริการของเราถูกบล็อกในประเทศของคุณ"; +"purchase.confirm.form.email" = "กรุณากรอกอีเมลของคุณ"; +"purchase.confirm.plan" = "คุณกำลังซื้อแผน %@"; +"purchase.email.why" = "โปรดแจ้งอีเมลสำหรับส่งชื่อผู้ใช้และรหัสผ่านของคุณ"; +"purchase.submit" = "ส่ง"; +"purchase.or" = "หรือ"; + +"upgrade.header" = "ยินดีต้อนรับกลับมา!"; +"upgrade.title" = "หากต้องการใช้ Private Internet Access คุณจะต้องต่ออายุสมาชิกของคุณ"; +"upgrade.renew.now" = "ต่ออายุตอนนี้"; + + + +"redeem.title" = "ใช้สิทธิ์บัตรของขวัญ"; +"redeem.subtitle" = "พิมพ์ที่อยู่อีเมลของคุณและ PIN %lu หลักจากบัตรของขวัญหรือบัตรทดลองด้านล่าง"; +"redeem.email.placeholder" = "ที่อยู่อีเมล"; +"redeem.submit" = "ส่ง"; +"redeem.error.title" = "ใช้สิทธิ์"; +"redeem.error.code" = "รหัสต้องประกอบด้วยตัวเลข %lu หลัก"; +"redeem.error.allfields" = "กรุณากรอกอีเมลและ PIN"; +"redeem.accessibility.back" = "กลับ"; +"redeem.giftcard.placeholder" = "PIN บัตรของขวัญ"; + +"plan.monthly.title" = "รายเดือน"; +"plan.yearly.title" = "รายปี"; +"plan.yearly.detail_format" = "%@%@ ต่อปี"; +"plan.price_format" = "%@/เดือน"; +"plan.best_value" = "คุ้มค่าที่สุด"; +"plan.accessibility.per_month" = "ต่อเดือน"; + +"restore.title" = "คืนค่าการซื้อยังไม่ได้คิดเครดิต"; +"restore.subtitle" = "หากคุณทำการซื้อแผนผ่านแอพนี้และยังไม่ได้รับข้อมูลประจำตัว คุณสามารถส่งอีกครั้งได้จากที่นี่ คุณจะไม่ถูกเรียกเก็บเงินซ้ำอีกครั้งในกระบวนการนี้"; +"restore.email.placeholder" = "อีเมลแอดเดรส"; +"restore.submit" = "ยืนยัน"; + +"iap.error.message.unavailable" = "ไม่พบเซิร์ฟเวอร์แอปเปิ้ลในขณะนี้ โปรดลองใหม่ภายหลัง"; +"iap.error.title" = "ข้อผิดพลาด"; + +"agreement.trials.title" = "ข้อกำหนดและเงื่อนไขการทดลองใช้ฟรี"; +"agreement.trials.message" = "ยอดชำระเงินจะถูกหักจากบัญชี Apple ID ของคุณเมื่อมีการยืนยันคำสั่งซื้อ ระบบจะต่ออายุสมาชิกโดยอัตโนมัติเว้นแต่จะมีการยกเลิกล่วงหน้าอย่างน้อย 24 ชั่วโมงก่อนที่จะสิ้นสุดรอบใช้งานปัจจุบัน บัญชีของคุณจะถูกเรียกเก็บเงินค่าต่ออายุสมาชิกภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบใช้งานปัจจุบัน คุณสามารถจัดการและยกเลิกการเป็นสมาชิกได้โดยไปที่การตั้งค่าบัญชีใน App Store หลังจากซื้อแล้ว\n\nบางระบบสมาชิกแบบชำระเงินอาจเสนอให้คุณทดลองใช้ฟรีก่อนที่จะเรียกเก็บเงินผ่านช่องทางการชำระเงินที่คุณเลือกไว้ หากคุณตัดสินใจที่จะยกเลิกการสมัครสมาชิกแบบชำระเงินก่อนที่เราจะเริ่มเรียกเก็บเงินผ่านช่องทางการชำระเงินที่เลือกไว้ ให้ทำการยกเลิกสมาชิกล่วงหน้าอย่างน้อย 24 ชั่วโมงก่อนที่ช่วงทดลองใช้ฟรีจะสิ้นสุดลง\n\nสามารถทดลองใช้ฟรีเฉพาะผู้ใช้ใหม่เท่านั้นและขึ้นอยู่กับดุลยพินิจของเราแต่เพียงผู้เดียว และหากคุณพยายามที่จะสมัครเพื่อทดลองใช้ฟรีซ้ำอีก คุณจะถูกเรียกเก็บค่าธรรมเนียมการสมัครสมาชิกตามมาตรฐานทันที\n\nเราขอสงวนสิทธิ์ในการเพิกถอนสิทธิ์ทดลองใช้ฟรีของคุณได้ตลอดเวลา\n\nส่วนที่ไม่ได้ใช้งานของช่วงทดลองใช้ฟรีจะถูกหักทิ้งเมื่อมีการสมัครสมาชิก\n\nการสมัครสมาชิกถือว่าเป็นการยอมรับข้อกำหนดและเงื่อนไขนี้"; +"agreement.message" = "หลังจากทดลองใช้ฟรี 7 วัน ระบบจะต่ออายุสมาชิกนี้โดยอัตโนมัติในราคา %@ เว้นแต่จะมีการยกเลิกล่วงหน้าอย่างน้อย 24 ชั่วโมงก่อนที่จะสิ้นสุดรอบใช้งานปัจจุบัน บัญชี Apple ID ของคุณจะถูกเรียกเก็บเงินค่าต่ออายุสมาชิกภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบใช้งานปัจจุบัน คุณสามารถจัดการและยกเลิกการเป็นสมาชิกได้โดยไปที่การตั้งค่าบัญชีใน App Store หลังจากซื้อแล้ว จำกัดสิทธิ์การทดลองใช้ฟรี 7 วัน เพียง 1 สิทธิ์ต่อผู้ใช้หนึ่งราย ส่วนที่ไม่ได้ใช้งานของช่วงทดลองใช้ฟรีหากมีให้จะถูกริบเมื่อผู้ใช้ซื้อการสมัครสมาชิก ราคาทั้งหมดรวมภาษีการขายในท้องที่\n\nการลงทะเบียนจะถือว่าคุณยินยอมตาม $1 และ $2"; +"agreement.trials.yearly.plan" = "ปี"; +"agreement.trials.monthly.plan" = "เดือน"; + +"agreement.message.tos" = "ข้อตกลงการใช้บริการ"; +"agreement.message.privacy" = "นโยบายความเป็นส่วนตัว"; + +"getstarted.buttons.buyaccount" = "ซื้อบัญชี"; + +"gdpr.collect.data.title" = "ข้อมูลส่วนบุคคลที่เรารวบรวม"; +"gdpr.collect.data.description" = "อีเมลเพื่อจุดประสงค์ในการจัดการและการป้องกันบัญชีจากการใช้งานในทางที่ผิด"; +"gdpr.usage.data.title" = "การใช้ข้อมูลส่วนบุคคลที่เรารวบรวม"; +"gdpr.usage.data.description" = "ที่อยู่อีเมลใช้ในการส่งข้อมูลการสมัครสมาชิก การยืนยันการชำระเงิน การติดต่อกับลูกค้า และข้อเสนอส่งเสริมการขาย Private Internet Access เท่านั้น"; +"gdpr.accept.button.title" = "ยอมรับและดำเนินการต่อ"; + +"update.account.email.error" = "ไม่สามารถแก้ไขอีเมลบัญชีได้"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings new file mode 100644 index 000000000..36d6ad53a --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings @@ -0,0 +1,166 @@ +/* (No Comment) */ +"failure.message" = "Şu anda hesap oluşturamıyoruz.\nLütfen daha sonra tekrar deneyin.\n\nUygulama yeniden açıldığından hesap oluşturma tekrar denenecektir."; + +/* (No Comment) */ +"failure.purchase.sandbox.message" = "Seçilen Sandbox aboneliği üretim ortamında mevcut değil."; + +/* (No Comment) */ +"failure.redeem.claimed.message" = "Bu kart önceden başka bir hesap tarafından talep edilmiş. Farklı bir PIN girmeyi deneyebilirsiniz."; + +/* (No Comment) */ +"failure.redeem.claimed.title" = "Kart önceden talep edilmiş"; + +/* (No Comment) */ +"failure.redeem.invalid.message" = "Görünüşe bakılırsa geçersiz bir kart PIN'i girdiniz. Lütfen tekrar deneyin."; + +/* (No Comment) */ +"failure.redeem.invalid.title" = "Geçersiz kart PIN'i"; + +/* (No Comment) */ +"failure.submit" = "GERİ DÖN"; + +/* (No Comment) */ +"failure.title" = "Hesap Oluşturma Hatası"; + +/* (No Comment) */ +"failure.vc_title" = "Kaydolma başarısız oldu"; + +/* (No Comment) */ +"in_progress.message" = "Sistemimizle satın alım işleminizi onaylıyoruz. Biraz zaman alabilir; lütfen bekleyin."; + +/* (No Comment) */ +"in_progress.redeem.message" = "Kart PIN'inizi sistemimizde onaylıyoruz. Bu biraz zaman alabilir, lütfen bekleyin."; + +/* Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. */ +"in_progress.title" = "Kaydolmayı onayla"; + +/* (No Comment) */ +"purchase.subscribe.now" = "Hemen abone ol"; + +/* (No Comment) */ +"purchase.trials.1year.protection" = "1 yıllık gizlilik ve kimlik koruması"; + +/* (No Comment) */ +"purchase.trials.all.plans" = "Tüm mevcut planlara bakın"; + +/* (No Comment) */ +"purchase.trials.anonymous" = "IP'nizi gizleyerek İnternet'te isimsiz gezinin."; + +/* (No Comment) */ +"purchase.trials.devices" = "Aynı anda 10 cihaz desteği"; + +/* (No Comment) */ +"purchase.trials.devices.description" = "Aynı anda 10 cihazda kendinizi koruyun."; + +/* (No Comment) */ +"purchase.trials.intro" = "7 günlük ücretsiz deneme sürenizi başlatın"; + +/* (No Comment) */ +"purchase.trials.money.back" = "30 günlük para iade garantisi"; + +/* (No Comment) */ +"purchase.trials.price.after" = "Ardından %@"; + +/* (No Comment) */ +"purchase.trials.region" = "Tüm bölgelere kolayca bağlanın"; + +/* (No Comment) */ +"purchase.trials.servers" = "32 ülkede en az 3.300 sunucu"; + +/* (No Comment) */ +"purchase.trials.start" = "Aboneliği başlat"; + +/* (No Comment) */ +"purchase.uncredited.alert.button.cancel" = "İptal"; + +/* (No Comment) */ +"purchase.uncredited.alert.button.recover" = "Hesabı kurtar"; + +/* (No Comment) */ +"purchase.uncredited.alert.message" = "Hesaba yansıtılmamış olan işlemleriniz var. Hesap bilgilerinizi kurtarmak ister misiniz?"; + +/* (No Comment) */ +"share.data.buttons.accept" = "Kabul Et"; + +/* (No Comment) */ +"share.data.buttons.noThanks" = "Hayır, teşekkürler"; + +/* (No Comment) */ +"share.data.buttons.readMore" = "Devamını oku"; + +/* (No Comment) */ +"share.data.readMore.text.description" = "Bu asgari bilgi, potansiyel bağlantı sorunlarını tanımlayıp düzeltmemize yardımcı olur. Bu bilgiyi paylaşmak için onay verilmesi ve varsayılan olarak kapalı olduğu için elle etkinleştirilmesi gerektiğini dikkate alın.\n\nŞu olaylarla ilgili bilgi toplayacağız:\n\n - Bağlantı Denemesi\n - Bağlantı İptal Edildi\n - Bağlantı Kuruldu\n\nTüm bu olaylar için şu bilgileri toplayacağız:\n - Platform\n - Uygulama sürümü\n - Uygulama türü (ön sürüm olup olmadığı)\n - Kullanılan protokol\n - Bağlantı kaynağı (manuel ya da otomasyon ile)\n\nTüm olaylarda rastgele oluşturulan eşsiz bir kimlik yer alacak. Bu kimlik kullanıcı hesabınızla bağlantılı değildir. Bu eşsiz kimlik, gizliliğin korunması açısından günlük olarak üretilir.\n\nKontrol daima sizde olacak. Ayarlardan hangi verileri topladığımızı görebilir ve bunu istediğiniz zaman kapatabilirsiniz."; + +/* (No Comment) */ +"share.data.text.description" = "Hizmetimizin bağlantı performansını korumamıza yardımcı olmak için bağlantı istatistiklerinizi isimsiz olarak bizimle paylaşabilirsiniz. Bu raporlarda kişiyi tanımlayabilecek herhangi bir bilgi yer almaz."; + +/* (No Comment) */ +"share.data.text.footer" = "Bunu istediğiniz zaman ayarlarınızdan kontrol edebilirsiniz"; + +/* (No Comment) */ +"share.data.text.title" = "Lütfen hizmetimizi geliştirmemize yardım edin"; + +/* (No Comment) */ +"success.message_format" = "Bize kayıt olduğunuz için teşekkürler. Hesap kullanıcı adı ve parolanızı %@ e-posta adresinize gönderdik"; + +/* (No Comment) */ +"success.password.caption" = "Şifre"; + +/* (No Comment) */ +"success.redeem.message" = "Kısa süre içinde kullanıcı adınızı ve şifrenizi içeren bir e-posta alacaksınız.\n\nGiriş bilgileriniz"; + +/* (No Comment) */ +"success.redeem.title" = "Kart başarıyla kullanıldı"; + +/* (No Comment) */ +"success.submit" = "Başlarken"; + +/* (No Comment) */ +"success.title" = "Satın Alma Tamamlandı"; + +/* (No Comment) */ +"success.username.caption" = "Kullanıcı Adı"; + +/* (No Comment) */ +"unreachable.message" = "İnternet bağlantısı yok. Lütfen İnternet bağlantınız olup olmadığını kontrol edin ve tekrar aşağıya tıklamayı deneyin.\n\nİşlemi bitirmek için uygulamaya daha sonra tekrar gelebilirsiniz."; + +/* (No Comment) */ +"unreachable.submit" = "TEKRAR DENE"; + +/* (No Comment) */ +"unreachable.title" = "Heeey!"; + +/* (No Comment) */ +"unreachable.vc_title" = "Hata"; + +/* (No Comment) */ +"walkthrough.action.done" = "BİTTİ"; + +/* WALKTHROUGH */ +"walkthrough.action.next" = "İLERİ"; + +/* (No Comment) */ +"walkthrough.action.skip" = "ATLA"; + +/* (No Comment) */ +"walkthrough.page.1.description" = "Aynı anda 10 cihazda koruma sağlayın."; + +/* (No Comment) */ +"walkthrough.page.1.title" = "Aynı anda 10 cihazı destekler"; + +/* (No Comment) */ +"walkthrough.page.2.description" = "Dünya çapındaki sunucularla daima koruma altındasınız."; + +/* (No Comment) */ +"walkthrough.page.2.title" = "Herhangi bir bölgeye kolayca bağlanın"; + +/* (No Comment) */ +"walkthrough.page.3.description" = "İçerik Engelleyicimizi etkinleştirdiğinizde Safari'de reklamların gösterilmesi engellenir."; + +/* (No Comment) */ +"walkthrough.page.3.title" = "Kendinizi reklamlardan koruyun"; + diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings new file mode 100644 index 000000000..fc6795eb9 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings @@ -0,0 +1,12 @@ +/* (No Comment) */ +"global.cancel" = "İptal"; + +/* (No Comment) */ +"global.close" = "Kapat"; + +/* (No Comment) */ +"global.ok" = "Tamam"; + +/* (No Comment) */ +"global.version.format" = "Sürüm %@ (%@)"; + diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings new file mode 100644 index 000000000..49d7ab5ca --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings @@ -0,0 +1,205 @@ +/* (No Comment) */ +"agreement.message" = "Bu abonelik, deneme süresinin sonuna en az 24 saat kalana dek iptal edilmezse, otomatik olarak %@ karşılığında yenilenir. Deneme süresinin sonuna 24 saat kaldıktan sonra, Apple Kimliğinizin hesabından yenileme ücreti alınır. Satın alım işleminden sonra App Store hesap ayarlarına giderek abonelik ayarlarınızı değiştirebilir ve aboneliklerinizi iptal edebilirsiniz. 7 günlük deneme süresi, her kullanıcı için bir tane 7 günlük deneme süresi hakkı ile sınırlıdır. Kullanıcı bir abonelik satın aldığında, teklif edilmişse, ücretsiz deneme süresinin kullanılmayan herhangi bir kısmı geçerliliğini yitirir. Tüm fiyatlara uygulanabilir yerel satış vergileri dahildir.\n\nKaydolduğunuzda, $1 ile $2 unsurlarını kabul etmiş olursunuz."; + +/* (No Comment) */ +"agreement.message.privacy" = "Gizlilik Politikası"; + +/* (No Comment) */ +"agreement.message.tos" = "Hizmet Koşulları"; + +/* (No Comment) */ +"agreement.trials.message" = "Satın alım onaylandıktan sonra, ödeme ücreti, Apple Kimliği hesabınızdan alınır. Mevcut dönemin sonuna en az 24 saat kalana dek iptal edilmezse, abonelik otomatik olarak yenilenir. Mevcut dönemin sonuna 24 saat kaldıktan sonra hesabınızdan yenileme ücreti alınır. Satın alım işleminden sonra App Store'daki hesap ayarlarınıza giderek abonelik ayarlarınızı değiştirebilir ve aboneliğinizi iptal edebilirsiniz.\n\nBelirli Ücretli Abonelik planlarında, seçtiğiniz ödeme yöntemiyle ücret alınmadan önce, bir ücretsiz kullanım süresi sunulabilir. Seçtiğiniz ödeme yöntemiyle sizden ücret almaya başlamamızdan önce Ücretli Aboneliğinizi iptal etmek isterseniz, ücretsiz kullanım süresinin sonuna en az 24 saat kalana dek aboneliğinizi iptal etmelisiniz.\n\nÜcretsiz deneme süresinden sadece yeni kullanıcılar faydalanabilir ve bu tamamen bizim takdirimizdedir. Tekrar kaydolarak bir ücretsiz deneme süresi daha almaya çalışırsanız, standart Abonelik Ücreti anında hesabınızdan düşülür.\n\nÜcretsiz deneme sürenizi istediğimiz zaman iptal etme hakkına sahibiz.\n\nBir abonelik satın aldığınızda, ücretsiz kullanım sürenizin kullanılmayan kısmını yitirirsiniz.\n\nKaydolduğunuzda bu şart ve koşulları kabul etmiş olursunuz."; + +/* (No Comment) */ +"agreement.trials.monthly.plan" = "ay"; + +/* (No Comment) */ +"agreement.trials.title" = "Ücretsiz deneme süresi şart ve koşulları"; + +/* (No Comment) */ +"agreement.trials.yearly.plan" = "yıl"; + +/* (No Comment) */ +"gdpr.accept.button.title" = "Kabul edip devam et"; + +/* (No Comment) */ +"gdpr.collect.data.description" = "Hesap yönetimi ve ihlalden koruma için E-posta Adresi."; + +/* (No Comment) */ +"gdpr.collect.data.title" = "Topladığımız kişisel bilgiler"; + +/* (No Comment) */ +"gdpr.usage.data.description" = "E-posta adresi sadece abonelik bilgilerinin, ödeme onaylarının, müşteri iletişim unsurlarının ve Private Internet Access'in promosyonel tekliflerinin gönderilmesi için kullanılır."; + +/* (No Comment) */ +"gdpr.usage.data.title" = "Tarafımızca toplanan kişisel bilgilerin kullanım şekilleri"; + +/* (No Comment) */ +"getstarted.buttons.buyaccount" = "Hesap satın al"; + +/* (No Comment) */ +"iap.error.message.unavailable" = "Apple sunucuları şu anda kullanılamıyor. Lütfen daha sonra tekrar deneyin."; + +/* (No Comment) */ +"iap.error.title" = "Hata"; + +/* (No Comment) */ +"login.error.throttled" = "Bu kullanıcı adı ile çok fazla kez yanlış giriş yapıldı. Lütfen daha sonra tekrar deneyin."; + +/* (No Comment) */ +"login.error.title" = "Giriş yap"; + +/* (No Comment) */ +"login.error.unauthorized" = "Kullanıcı adınız ya da şifreniz hatalı."; + +/* (No Comment) */ +"login.error.validation" = "Bir kullanıcı adı ve şifre girmelisiniz."; + +/* (No Comment) */ +"login.magic.link.invalid.email" = "E-posta adresi geçersiz. Lütfen tekrar deneyin."; + +/* (No Comment) */ +"login.magic.link.response" = "Giriş linkini bulmak için lütfen e-postalarınıza bakın."; + +/* (No Comment) */ +"login.magic.link.send" = "Link Gönder"; + +/* (No Comment) */ +"login.magic.link.title" = "Sihirli e-posta linki ile giriş yap"; + +/* (No Comment) */ +"login.password.placeholder" = "Şifre"; + +/* (No Comment) */ +"login.receipt.button" = "Satın alım faturasıyla giriş yapın"; + +/* (No Comment) */ +"login.restore.button" = "Hesap bilgilerinizi almadınız mı?"; + +/* (No Comment) */ +"login.submit" = "GİRİŞ YAP"; + +/* Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. */ +"login.title" = "Hesabınıza giriş yapın"; + +/* (No Comment) */ +"login.username.placeholder" = "Kullanıcı Adı (p1234567)"; + +/* (No Comment) */ +"plan.accessibility.per_month" = "aylık"; + +/* (No Comment) */ +"plan.best_value" = "En iyi fiyat"; + +/* (No Comment) */ +"plan.monthly.title" = "Aylık"; + +/* (No Comment) */ +"plan.price_format" = "%@/ay"; + +/* (No Comment) */ +"plan.yearly.detail_format" = "Yılda %@%@"; + +/* (No Comment) */ +"plan.yearly.title" = "Yıllık"; + +/* (No Comment) */ +"purchase.confirm.form.email" = "E-posta adresinizi girin"; + +/* (No Comment) */ +"purchase.confirm.plan" = "%@ planını satın alıyorsunuz"; + +/* (No Comment) */ +"purchase.continue" = "Devam et"; + +/* (No Comment) */ +"purchase.email.placeholder" = "E-posta adresi"; + +/* (No Comment) */ +"purchase.email.why" = "Kullanıcı adınızla şifrenizi gönderebilmemiz için e-posta adresinize ihtiyacımız var."; + +/* (No Comment) */ +"purchase.error.connectivity.description" = "Özel İnternet Erişimi'ne ulaşamıyoruz. Bu zayıf internet yüzünden olabilir veya hizmetimiz ülkenizde engelleniyor."; + +/* (No Comment) */ +"purchase.error.connectivity.title" = "Bağlantı Hatası"; + +/* (No Comment) */ +"purchase.error.title" = "Satın Al"; + +/* (No Comment) */ +"purchase.error.validation" = "Bir e-posta adresi girmeniz gerekiyor."; + +/* (No Comment) */ +"purchase.login.button" = "Giriş yapın"; + +/* (No Comment) */ +"purchase.login.footer" = "Hesabınız var mı?"; + +/* (No Comment) */ +"purchase.or" = "veya"; + +/* (No Comment) */ +"purchase.submit" = "Gönder"; + +/* (No Comment) */ +"purchase.subtitle" = "30 günlük para iade garantisi"; + +/* (No Comment) */ +"purchase.title" = "Bir VPN planı seçin"; + +/* (No Comment) */ +"redeem.accessibility.back" = "Geri"; + +/* (No Comment) */ +"redeem.email.placeholder" = "E-posta adresi"; + +/* (No Comment) */ +"redeem.error.allfields" = "Lütfen e-posta adresinizi ve kart PIN numaranızı girin."; + +/* (No Comment) */ +"redeem.error.code" = "Kod, %lu sayısal haneden oluşmalıdır."; + +/* (No Comment) */ +"redeem.error.title" = "Kullan"; + +/* (No Comment) */ +"redeem.giftcard.placeholder" = "Hediye kartı ve PIN"; + +/* (No Comment) */ +"redeem.submit" = "Gönder"; + +/* (No Comment) */ +"redeem.subtitle" = "E-posta adresinizi ve hediye kartınızdaki ya da deneme kartınızdaki %lu haneli PIN'i aşağıya girin."; + +/* (No Comment) */ +"redeem.title" = "Hediye kartını kullan"; + +/* (No Comment) */ +"restore.email.placeholder" = "E-posta adresi"; + +/* (No Comment) */ +"restore.submit" = "ONAYLA"; + +/* (No Comment) */ +"restore.subtitle" = "Bu uygulamadan bir plan satın aldıktan sonra hesap bilgilerinizi alamadıysanız, onları buradan tekrar gönderebilirsiniz. Bu işlem esnasında sizden ücret alınmayacak."; + +/* (No Comment) */ +"restore.title" = "Bilgileri gönderilmeyen satın alma işlemini tekrarlayın"; + +/* (No Comment) */ +"update.account.email.error" = "Hesap e-posta adresi değiştirilemedi"; + +/* (No Comment) */ +"upgrade.header" = "Tekrar Hoş Geldiniz!"; + +/* (No Comment) */ +"upgrade.renew.now" = "Hemen yenileyin"; + +/* (No Comment) */ +"upgrade.title" = "Private Internet Access kullanabilmek için aboneliğinizi yenilemeniz gerekiyor."; + diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings new file mode 100644 index 000000000..2f4afbb78 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "确认注册"; +"in_progress.message" = "我们正在确认您在我们系统中的购买。这可能需要一点时间,请耐心等待。"; +"in_progress.redeem.message" = "我们正在通过系统确认您的卡片PIN。这可能需要一些时间,请耐心等待。"; + +"success.title" = "购买完成"; +"success.message_format" = "感谢注册。我们已将您的用户名和密码发送至您的电子邮箱:%@"; +"success.redeem.title" = "卡片兑换成功"; +"success.redeem.message" = "您将很快收到一封电子邮件,记有您的用户名和密码。\n\n您的登录详情"; +"success.username.caption" = "用户名"; +"success.password.caption" = "密码"; +"success.submit" = "开始体验"; + +"failure.vc_title" = "注册失败"; +"failure.title" = "账户创建失败"; +"failure.message" = "我们现在无法创建账号。\n请稍后再试。\n\n重新打开本应用将会再次尝试创建账号。"; +"failure.purchase.sandbox.message" = "所选的沙盒订阅不适用于生产"; +"failure.redeem.invalid.title" = "卡片PIN无效"; +"failure.redeem.invalid.message" = "您输入的卡片PIN似乎无效。请重试。"; +"failure.redeem.claimed.title" = "卡片已使用"; +"failure.redeem.claimed.message" = "此卡片似乎已被另一个账号使用。您可尝试输入另一个PIN。"; +"failure.submit" = "返回"; + +"unreachable.vc_title" = "错误"; +"unreachable.title" = "糟糕!"; +"unreachable.message" = "未找到网络连接。请确认您已接入网络,然后点击下面的重试。\n\n您可在稍后再回到本应用完成该操作。"; +"unreachable.submit" = "重试"; + +"purchase.uncredited.alert.message" = "你有未入账的的交易。要恢复您的账户详情吗?"; +"purchase.uncredited.alert.button.cancel" = "取消"; +"purchase.uncredited.alert.button.recover" = "恢复账户"; + +"purchase.trials.intro" = "开始 7 天免费试用"; +"purchase.trials.price.after" = "然后 %@"; +"purchase.trials.money.back" = "7 天退款保证"; +"purchase.trials.1year.protection" = "1 年隐私和身份保护"; +"purchase.trials.anonymous" = "匿名浏览并隐藏您的 IP。"; +"purchase.trials.devices" = "一次支持 10 台设备"; +"purchase.trials.devices.description" = "一次在多达 10 台设备上保护自己。"; +"purchase.trials.region" = "轻松连接到任何地区"; +"purchase.trials.servers" = "在 32 个国家h地区拥有超过 3300 台服务器"; +"purchase.trials.start" = "开始订阅"; +"purchase.trials.all.plans" = "查看所有可用套餐"; + +"purchase.subscribe.now" = "立即订阅"; + +// WALKTHROUGH + +"walkthrough.action.next" = "下一个"; +"walkthrough.action.done" = "完成"; +"walkthrough.action.skip" = "跳过"; + +"walkthrough.page.1.title" = "一次支持 10 台设备"; +"walkthrough.page.1.description" = "一次在多达 10 台设备上保护自己。"; +"walkthrough.page.2.title" = "轻松连接到任何地区"; +"walkthrough.page.2.description" = "服务器遍布世界各地,您始终受到保护。"; +"walkthrough.page.3.title" = "让自己远离广告"; +"walkthrough.page.3.description" = "启用内容拦截器以防止 Safari 中出现广告。"; + +"share.data.buttons.accept" = "接受"; +"share.data.buttons.noThanks" = "不用,谢谢"; +"share.data.buttons.readMore" = "阅读更多"; +"share.data.text.title" = "请帮助我们改进服务"; +"share.data.text.description" = "为了帮助我们保持服务的连接性能,您可以匿名与我们共享您的连接统计数据。这些报告不包括任何可识别个人身份的信息。"; +"share.data.text.footer" = "您始终可以从设置中进行控制"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings new file mode 100644 index 000000000..e6f012399 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "版本 %@ (%@)"; +"global.close" = "关闭"; +"global.ok" = "确定"; +"global.cancel" = "取消"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings new file mode 100644 index 000000000..8d5c7e113 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "登录到您的帐户"; +"login.username.placeholder" = "用户名 (p1234567)"; +"login.password.placeholder" = "密码"; +"login.submit" = "登录"; +"login.restore.button" = "没有收到账户详情?"; +"login.error.title" = "登录"; +"login.error.validation" = "您必须输入用户名和密码。"; +"login.error.unauthorized" = "您的用户名或密码不正确。"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "使用购买收据登录"; +"login.magic.link.title" = "使用魔法电子邮件链接登录"; +"login.magic.link.response" = "请检查您的电子邮件,以查找登录链接。"; +"login.magic.link.send" = "发送链接"; +"login.magic.link.invalid.email" = "电子邮箱乎无效。请重试。"; + +"purchase.title" = "选择 VPN 套餐"; +"purchase.subtitle" = "7 天退款保证"; +"purchase.email.placeholder" = "电子邮件地址"; +"purchase.continue" = "继续"; +"purchase.login.footer" = "已有帐号?"; +"purchase.login.button" = "登录"; +"purchase.error.title" = "购买"; +"purchase.error.validation" = "您必须输入一个电子邮箱地址。"; +"purchase.error.connectivity.title" = "连接失败"; +"purchase.error.connectivity.description" = "我们无法接入Private Internet Access。原因可能是互联网连接不良或者我们的服务在您的国家遭到屏蔽。"; +"purchase.confirm.form.email" = "请输入您的电子邮件地址"; +"purchase.confirm.plan" = "您正在购买 %@ 套餐"; +"purchase.email.why" = "我们需要您的电子邮件以发送您的用户名和密码。"; +"purchase.submit" = "提交"; +"purchase.or" = "或"; + +"upgrade.header" = "欢迎回来!"; +"upgrade.title" = "您需要续订才能使用 Private Internet Access。"; +"upgrade.renew.now" = "立即续订"; + + + +"redeem.title" = "兑换礼品卡"; +"redeem.subtitle" = "请输入您的电子邮箱地址以及礼品卡或试用卡上的%lu位数字PIN。"; +"redeem.email.placeholder" = "邮箱地址"; +"redeem.submit" = "提交"; +"redeem.error.title" = "兑换"; +"redeem.error.code" = "PIN码必须包含%lu个数字。"; +"redeem.error.allfields" = "请输入您的电子邮件和卡片 PIN 码。"; +"redeem.accessibility.back" = "返回"; +"redeem.giftcard.placeholder" = "礼品卡 PIN"; + +"plan.monthly.title" = "每月"; +"plan.yearly.title" = "每年"; +"plan.yearly.detail_format" = "%@%@/每年"; +"plan.price_format" = "%@/每月"; +"plan.best_value" = "最超值"; +"plan.accessibility.per_month" = "每月"; + +"restore.title" = "恢复未入账的购买"; +"restore.subtitle" = "如果您通过此 app 购买了套餐,但没有收到凭据,可以从这里重新发送。在此过程中您不会被收费。"; +"restore.email.placeholder" = "电子邮件地址"; +"restore.submit" = "确认"; + +"iap.error.message.unavailable" = "Apple 服务器目前不可用。请稍后重试。"; +"iap.error.title" = "错误"; + +"agreement.trials.title" = "免费试用条款和条件"; +"agreement.trials.message" = "确认购买后,将从您的 Apple ID 账户中收取款项。除非在当前使用期结束前至少提前 24 小时取消,否则会自动续订。您的账户将在当前使用期结束前 24 小时内收取续订费用。您可以在购买后前往 App Store 上的账户设置来管理和取消订阅。\n\n某些“付费订阅”可能会在向您收取款项之前先提供免费试用。如果您在我们开始收取款项之前决定取消订阅“付费订阅”,请在免费试用结束前至少提前 24 小时取消订阅。\n\n免费试用仅适用于新用户,并由我们自行决定,如果您尝试注册额外的免费试用,您将被立即收取标准订阅费。\n\n我们有权随时撤销您的免费试用。\n\n免费试用期的任何未使用部分将在购买订阅时取消。\n\n注册即表示接受上述条款和条件。"; +"agreement.message" = "免费试用 7 天后,除非在试用期结束前至少提前 24 小时取消,否则此订阅将自动续订 %@。您的 Apple ID 账户将在试用期结束前 24 小时内收取续订费用。您可以在购买后前往 App Store 上的账户设置来管理和取消订阅。每个用户仅可享受一次 7 天试用优惠。免费试用期的任何未使用部分(如果提供)将在用户购买订阅时失效。所有价格均包含适用的当地营业税。\n\n注册即表示接受$1和$2。"; +"agreement.trials.yearly.plan" = "年"; +"agreement.trials.monthly.plan" = "月"; + +"agreement.message.tos" = "服务条款"; +"agreement.message.privacy" = "隐私政策"; + +"getstarted.buttons.buyaccount" = "购买账户"; + +"gdpr.collect.data.title" = "我们收集的个人信息"; +"gdpr.collect.data.description" = "用于账户管理和防止滥用的电子邮件地址。"; +"gdpr.usage.data.title" = "我们收集的个人信息的使用方式"; +"gdpr.usage.data.description" = "电子邮件地址仅用于发送订阅信息、付款确认、客户通信以及 Private Internet Access 促销优惠。"; +"gdpr.accept.button.title" = "同意并继续"; + +"update.account.email.error" = "无法修改账户电子邮件"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings new file mode 100644 index 000000000..ed78c07e6 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "壓認註冊"; +"in_progress.message" = "我們的系統正確認您的購買交易,可能需要停留在此畫面幾分鐘時間。"; +"in_progress.redeem.message" = "我們的系統正在確認您的卡 PIN 碼。這可能需要一點時間,請稍候。"; + +"success.title" = "購買完成"; +"success.message_format" = "感謝您註冊我們的服務!我們已將您的帳戶使用者名稱和密碼寄送到您的電子郵件地址:%@"; +"success.redeem.title" = "已成功兌換禮品卡"; +"success.redeem.message" = "您很快就會收到一封電子郵件,內有使用者名稱及密碼。\n\n您的登入資料"; +"success.username.caption" = "使用者名稱"; +"success.password.caption" = "密碼"; +"success.submit" = "開始使用"; + +"failure.vc_title" = "註冊失敗"; +"failure.title" = "帳戶建立失敗"; +"failure.message" = "我們目前未能建立帳戶,請稍後再試。\n\n應用程式將在重新啟動時再次嘗試建立帳戶。"; +"failure.purchase.sandbox.message" = "所選的沙盒訂閱已不再提供。"; +"failure.redeem.invalid.title" = "無效的卡 PIN 碼"; +"failure.redeem.invalid.message" = "您似乎輸入了一個無效的卡 PIN 碼,請再試一次。"; +"failure.redeem.claimed.title" = "此卡已被使用"; +"failure.redeem.claimed.message" = "這張卡似乎已經被另一個帳戶使用。您可以嘗試輸入不同的 PIN 碼。"; +"failure.submit" = "返回"; + +"unreachable.vc_title" = "錯誤"; +"unreachable.title" = "噢!"; +"unreachable.message" = "找不到網路連線。請確定您已連線上網,然後點選下方按鈕重試。\n\n您可以稍後再回來完成程序。"; +"unreachable.submit" = "重試"; + +"purchase.uncredited.alert.message" = "您有未貸記的交易,要回復帳戶資料嗎?"; +"purchase.uncredited.alert.button.cancel" = "取消"; +"purchase.uncredited.alert.button.recover" = "回復帳戶"; + +"purchase.trials.intro" = "開始 7 天免費試用"; +"purchase.trials.price.after" = "然後 %@"; +"purchase.trials.money.back" = "30 天退款保證"; +"purchase.trials.1year.protection" = "1 年隱私權和身分保護"; +"purchase.trials.anonymous" = "匿名瀏覽並隱藏 IP。"; +"purchase.trials.devices" = "同時支援 10 台裝置"; +"purchase.trials.devices.description" = "同時為最多 10 台裝置提供保護。"; +"purchase.trials.region" = "可輕鬆連線到任何地區"; +"purchase.trials.servers" = "32 個國家超過 3300 台伺服器"; +"purchase.trials.start" = "開始訂閱"; +"purchase.trials.all.plans" = "檢視所有可用方案"; + +"purchase.subscribe.now" = "馬上訂閱"; + +// WALKTHROUGH + +"walkthrough.action.next" = "下一步"; +"walkthrough.action.done" = "完成"; +"walkthrough.action.skip" = "跳過"; + +"walkthrough.page.1.title" = "同時支援 10 台裝置"; +"walkthrough.page.1.description" = "同時為多達 10 台裝置提供保護"; +"walkthrough.page.2.title" = "輕易就能連線到任何地區"; +"walkthrough.page.2.description" = "我們的伺服器遍佈全球,能為您提供全面保護。"; +"walkthrough.page.3.title" = "讓自己免受廣告滋擾"; +"walkthrough.page.3.description" = "只要啟用我們的內容阻擋器,使用 Safari 瀏覽器時就再也不會看到廣告。"; + +"share.data.buttons.accept" = "接受"; +"share.data.buttons.noThanks" = "不了,謝謝"; +"share.data.buttons.readMore" = "閱讀更多內容"; +"share.data.text.title" = "請協助我們改善服務"; +"share.data.text.description" = "為了確保服務的連線品質,您可以匿名與我們分享您的連線統計資料。這些報告不會包含任何個人識別資訊。"; +"share.data.text.footer" = "您隨時都可以在設定中控制。"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings new file mode 100644 index 000000000..7d68e2272 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "版本 %@ (%@)"; +"global.close" = "關閉"; +"global.ok" = "確認"; +"global.cancel" = "取消"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings new file mode 100644 index 000000000..b4c846e04 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "登入帳戶"; +"login.username.placeholder" = "使用者名稱(p1234567)"; +"login.password.placeholder" = "密碼"; +"login.submit" = "登入"; +"login.restore.button" = "收不到帳戶資料?"; +"login.error.title" = "登入"; +"login.error.validation" = "您必須輸入使用者名稱及密碼。"; +"login.error.unauthorized" = "您的使用者名稱或密碼不正確。"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "使用購買收據登入"; +"login.magic.link.title" = "使用神奇的電子郵件連結登入"; +"login.magic.link.response" = "請確認電子信箱是否已收到登入連結。"; +"login.magic.link.send" = "傳送連結"; +"login.magic.link.invalid.email" = "無效的電子郵件。請重試。"; + +"purchase.title" = "選擇 VPN 方案"; +"purchase.subtitle" = "30 天退款保證"; +"purchase.email.placeholder" = "電子郵件地址"; +"purchase.continue" = "繼續"; +"purchase.login.footer" = "已有帳號?"; +"purchase.login.button" = "登入"; +"purchase.error.title" = "購買"; +"purchase.error.validation" = "必須輸入電郵地址。"; +"purchase.error.connectivity.title" = "連線失敗"; +"purchase.error.connectivity.description" = "我們無法連線至 Private Internet Access。這可能是因為您的網路連線狀態不佳,或我們的服務在您的國家遭到封鎖。"; +"purchase.confirm.form.email" = "請輸入您的電子郵件地址"; +"purchase.confirm.plan" = "您正在購買 %@ 方案"; +"purchase.email.why" = "請提供電子郵件以便我們傳送使用者名稱及密碼。"; +"purchase.submit" = "提交"; +"purchase.or" = "或"; + +"upgrade.header" = "歡迎回來!"; +"upgrade.title" = "如果要使用 Private Internet Access,您必須續訂。"; +"upgrade.renew.now" = "立即續訂"; + + + +"redeem.title" = "兌換禮品卡"; +"redeem.subtitle" = "於下方輸入您的電子郵件地址及禮品卡或試用卡並的 %lu 位數 PIN 碼。"; +"redeem.email.placeholder" = "電子郵件地址"; +"redeem.submit" = "提交"; +"redeem.error.title" = "兌換"; +"redeem.error.code" = "代碼必須包含 %lu 個數字。"; +"redeem.error.allfields" = "請輸入您的電子郵件地址及禮品卡 PIN 碼。"; +"redeem.accessibility.back" = "返回"; +"redeem.giftcard.placeholder" = "禮品卡 PIN 碼"; + +"plan.monthly.title" = "月繳"; +"plan.yearly.title" = "年繳"; +"plan.yearly.detail_format" = "每年 %@%@"; +"plan.price_format" = "每月 %@"; +"plan.best_value" = "最佳值"; +"plan.accessibility.per_month" = "/ 月"; + +"restore.title" = "回復未貸記購買項目"; +"restore.subtitle" = "如果您透過此應用程式購買方案後收不到您的憑證,可以透過這裡要求再次傳送。此操作不會收取任何費用。"; +"restore.email.placeholder" = "電子郵件地址"; +"restore.submit" = "確定"; + +"iap.error.message.unavailable" = "Apple 伺服器目前無法使用,請稍後再試。"; +"iap.error.title" = "錯誤"; + +"agreement.trials.title" = "免費試用條款與條件"; +"agreement.trials.message" = "確認購買後,系統將從您的 Apple ID 帳號收取費用。除非您在目前訂閱期間結束前至少 24 小時取消訂閱,否則訂閱將自動續訂。在目前期間結束前 24 小時內,將從您的帳號收取續訂費用。您可在購買後,前往 App Store 的帳號設定管理和取消您的訂閱。\n\n「特定付費訂閱」可能在以您的付費方式收費前,提供免費試用。若您在我們開始以您的付費方式收費前,決定取消「付費訂閱」,請在免費試用結束前至少 24 小時取消訂閱。\n\n只有新使用者才享有免費試用的資格,且我們擁有唯一決定權。若您試圖再次註冊免費試用,我們會立即以「標準訂閱費用」向您收費。\n\n我們保留隨時解除您免費試用的權利。\n\n若您的免費試用有任何未使用的期間,將會在購買訂閱時收回。\n\n若註冊即代表您接受此條款與條件。"; +"agreement.message" = "免費試用 7 天後,除非您在試用期結束前至少 24 小時取消訂閱,否則系統將自動續訂 %@,並在試用期結束前的 24 小時內,從您的 Apple ID 帳號收取續訂費用。購買後,您可以前往 App Store 的帳號設定管理或取消您的訂閱方案。每位用戶只有一次 7 天試用的機會。若您的免費試用有任何未使用的期間,將會在購買訂閱時收回。所有價格已包括適用於當地的營業稅。\n\n若註冊,即代表您已接受 $1 與 $2。"; +"agreement.trials.yearly.plan" = "年"; +"agreement.trials.monthly.plan" = "月"; + +"agreement.message.tos" = "服務條款"; +"agreement.message.privacy" = "隱私權政策"; + +"getstarted.buttons.buyaccount" = "購買帳戶"; + +"gdpr.collect.data.title" = "我們收集的個人資料"; +"gdpr.collect.data.description" = "電子郵件地址用於管理帳戶及防止濫用。"; +"gdpr.usage.data.title" = "我們收集個人資料的用途"; +"gdpr.usage.data.description" = "電子郵件地址僅用於傳送訂閱資訊、付款確認函、客戶通訊及 Private Internet Access 的促銷優惠。"; +"gdpr.accept.button.title" = "同意並繼續"; + +"update.account.email.error" = "無法修改帳戶電子郵件"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/Info.plist b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/Info.plist new file mode 100644 index 000000000..11c8b1225 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/Info.plist differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem new file mode 100644 index 000000000..82dec692d --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem @@ -0,0 +1,43 @@ +-----BEGIN CERTIFICATE----- +MIIHqzCCBZOgAwIBAgIJAJ0u+vODZJntMA0GCSqGSIb3DQEBDQUAMIHoMQswCQYD +VQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNV +BAoTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIElu +dGVybmV0IEFjY2VzczEgMB4GA1UEAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3Mx +IDAeBgNVBCkTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkB +FiBzZWN1cmVAcHJpdmF0ZWludGVybmV0YWNjZXNzLmNvbTAeFw0xNDA0MTcxNzQw +MzNaFw0zNDA0MTIxNzQwMzNaMIHoMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex +EzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNVBAoTF1ByaXZhdGUgSW50ZXJuZXQg +QWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UE +AxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBCkTF1ByaXZhdGUgSW50 +ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkBFiBzZWN1cmVAcHJpdmF0ZWludGVy +bmV0YWNjZXNzLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALVk +hjumaqBbL8aSgj6xbX1QPTfTd1qHsAZd2B97m8Vw31c/2yQgZNf5qZY0+jOIHULN +De4R9TIvyBEbvnAg/OkPw8n/+ScgYOeH876VUXzjLDBnDb8DLr/+w9oVsuDeFJ9K +V2UFM1OYX0SnkHnrYAN2QLF98ESK4NCSU01h5zkcgmQ+qKSfA9Ny0/UpsKPBFqsQ +25NvjDWFhCpeqCHKUJ4Be27CDbSl7lAkBuHMPHJs8f8xPgAbHRXZOxVCpayZ2SND +fCwsnGWpWFoMGvdMbygngCn6jA/W1VSFOlRlfLuuGe7QFfDwA0jaLCxuWt/BgZyl +p7tAzYKR8lnWmtUCPm4+BtjyVDYtDCiGBD9Z4P13RFWvJHw5aapx/5W/CuvVyI7p +Kwvc2IT+KPxCUhH1XI8ca5RN3C9NoPJJf6qpg4g0rJH3aaWkoMRrYvQ+5PXXYUzj +tRHImghRGd/ydERYoAZXuGSbPkm9Y/p2X8unLcW+F0xpJD98+ZI+tzSsI99Zs5wi +jSUGYr9/j18KHFTMQ8n+1jauc5bCCegN27dPeKXNSZ5riXFL2XX6BkY68y58UaNz +meGMiUL9BOV1iV+PMb7B7PYs7oFLjAhh0EdyvfHkrh/ZV9BEhtFa7yXp8XR0J6vz +1YV9R6DYJmLjOEbhU8N0gc3tZm4Qz39lIIG6w3FDAgMBAAGjggFUMIIBUDAdBgNV +HQ4EFgQUrsRtyWJftjpdRM0+925Y6Cl08SUwggEfBgNVHSMEggEWMIIBEoAUrsRt +yWJftjpdRM0+925Y6Cl08SWhge6kgeswgegxCzAJBgNVBAYTAlVTMQswCQYDVQQI +EwJDQTETMBEGA1UEBxMKTG9zQW5nZWxlczEgMB4GA1UEChMXUHJpdmF0ZSBJbnRl +cm5ldCBBY2Nlc3MxIDAeBgNVBAsTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAw +HgYDVQQDExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UEKRMXUHJpdmF0 +ZSBJbnRlcm5ldCBBY2Nlc3MxLzAtBgkqhkiG9w0BCQEWIHNlY3VyZUBwcml2YXRl +aW50ZXJuZXRhY2Nlc3MuY29tggkAnS7684Nkme0wDAYDVR0TBAUwAwEB/zANBgkq +hkiG9w0BAQ0FAAOCAgEAJsfhsPk3r8kLXLxY+v+vHzbr4ufNtqnL9/1Uuf8NrsCt +pXAoyZ0YqfbkWx3NHTZ7OE9ZRhdMP/RqHQE1p4N4Sa1nZKhTKasV6KhHDqSCt/dv +Em89xWm2MVA7nyzQxVlHa9AkcBaemcXEiyT19XdpiXOP4Vhs+J1R5m8zQOxZlV1G +tF9vsXmJqWZpOVPmZ8f35BCsYPvv4yMewnrtAC8PFEK/bOPeYcKN50bol22QYaZu +LfpkHfNiFTnfMh8sl/ablPyNY7DUNiP5DRcMdIwmfGQxR5WEQoHL3yPJ42LkB5zs +6jIm26DGNXfwura/mi105+ENH1CaROtRYwkiHb08U6qLXXJz80mWJkT90nr8Asj3 +5xN2cUppg74nG3YVav/38P48T56hG1NHbYF5uOCske19F6wi9maUoto/3vEr0rnX +JUp2KODmKdvBI7co245lHBABWikk8VfejQSlCtDBXn644ZMtAdoxKNfR2WTFVEwJ +iyd1Fzx0yujuiXDROLhISLQDRjVVAvawrAtLZWYK31bY7KlezPlQnl/D9Asxe85l +8jO5+0LdJ6VyOs/Hd4w52alDW/MFySDZSfQHMTIc30hLBJ8OnCEIvluVQQ2UQvoW ++no177N9L2Y+M9TcTA62ZyMXShHQGeh20rb4kK8f+iFX8NxtdHVSkxMEFSfDDyQ= +-----END CERTIFICATE----- diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA.der b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA.der new file mode 100644 index 000000000..1bbbe477d Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA.der differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory new file mode 100644 index 000000000..bccd33843 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements new file mode 100644 index 000000000..dbf9d6144 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 new file mode 100644 index 000000000..f790851d8 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources new file mode 100644 index 000000000..2113d6bd3 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources @@ -0,0 +1,128 @@ + + + + + files + + PIA-RSA-4096.pem + + 3qHvNikZqOiKtbZEW5+oygpFyfw= + + PIA.der + + HjU73bSJKXFVdCTqzHVin0iWAak= + + + files2 + + PIA-RSA-4096.pem + + hash + + 3qHvNikZqOiKtbZEW5+oygpFyfw= + + hash2 + + Mumx0UM+qXYU8qFMbjWOP1fAVwzJ9rLugSaZumlsZqs= + + + PIA.der + + hash + + HjU73bSJKXFVdCTqzHVin0iWAak= + + hash2 + + H9JWWEVuqzBB+6d8zTmKuBJO3MG4svwdVf32sbv8nXA= + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature new file mode 100644 index 000000000..e69de29bb diff --git a/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/_CodeSignature/CodeResources b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/_CodeSignature/CodeResources new file mode 100644 index 000000000..6ae2e363e --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN Tunnel.appex/_CodeSignature/CodeResources @@ -0,0 +1,1745 @@ + + + + + files + + Info.plist + + koEREoV68vN8bCz5MLjXJ6u02jw= + + PIALibrary_PIALibrary.bundle/Assets.car + + 8h6Hyf4U9/+JlpRmAN3vBaPEjrw= + + PIALibrary_PIALibrary.bundle/Info.plist + + U4V2uvQAAIulAUfBSoJQTzWiVN4= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + dytHgVNc10hWhKQW+WIDasbWdTU= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib + + OVb1ASokoqm9FsqgYqS4ykOLvTk= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + qEnPzvZ7YJ2malb9v8b6uU1qRtI= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib + + BnH89TJFPy09hwlepgmy1qX8w5I= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist + + tvSnglTgEmfEVDs4Pqzq89zCWdk= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + htQTSxHbapTjr/KU4MZ+BReh+fg= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + CJa19sBIiRCsSpkmvlAK9WVgIUc= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib + + DClrKMNBhP7R57XPbVZNLZEkhHY= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib + + RII82MT1u8xiVhoF6z8GAPWRauw= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + YpRMevT/Hk92B7qxIoBZNubmhVo= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + bJ8pWQoqUwPJh2R449Z5iB80fgw= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + XIT4vTE0sbcaxPw4Ukcc10AudMU= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + 8QYAr5CSJVq9J2M/WNeKrHxyH4k= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + /KugdZ7rq/us89d7xS8Y4W80uoE= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + lAQN56rjGXobwkMhOfbs34FT+S8= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist + + /pYtZWavELI0+6nEkTUa0WNFSew= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + QLgeyu0ZVc/lDmyITQfrBSRT2Hk= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + gA8eOIpUQd1BEBgO/w9hDFS+JxU= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + GzhYGB3AyZ0wytBn61POuwdsJ7E= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + sQtUseVfpjT4CFtCBgvBwDjWfQA= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory + + gjf0PUSrcJskfjBJ7fSOp0hPRqU= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements + + OnX22wWFKRSOFN1+obRynMCeyXM= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 + + Xek7S2WT/EJTVDHjzmsxCQMBPMg= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources + + ypAPfIR7Xyk9v8RohL9v2uz3dB4= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature + + 2jmj7l5rSw0yVb/vlWAYkK/YBwk= + + PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings + + hash + + KDACaW+muq3Q7S2KFi/tSoBrOA0= + + optional + + + PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings + + hash + + q69blyRGQI14B9CBKT9Rsw4dq0k= + + optional + + + PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings + + hash + + BkACZwewt5pWHuYeiW8u/ttymCg= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings + + hash + + ImqHeuQyhd4vbb7tX6gDpc0Uws4= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/UI.strings + + hash + + JEB6TYMiWHIJ3Fwzv9hwS3X5B9c= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings + + hash + + 0U+OaxIpF3m54GcZw6Rj0FT9IQU= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings + + hash + + ULQLCKJ1Tkx5LYNqw+wZAPpz+fc= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/UI.strings + + hash + + 1964G9tW/vLUljfWDybLqmj8ovo= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings + + hash + + j/jLkt7lT5WaqzpSmS2HeZ2YT7g= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings + + hash + + EZ9QZ7PSibfcWSeEETK4rR/PkKE= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/UI.strings + + hash + + 8v4J37YS+jZq3LBvpRfFdfrmOjo= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings + + hash + + BwdYyKtC03avQBNFX31HfqSElzI= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings + + hash + + /cuvVUGtYOlubi9pgRpN8GF6eaQ= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings + + hash + + iiP5bcCQB5ClycQCkVGeHIMUAks= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings + + hash + + lx4/QzIqPJcVTvU4PUA9DuA+iR0= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings + + hash + + vRPh7xNvA8CBlDbvqId98Ppaol4= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings + + hash + + IbgvE2UN4PxyRd+exu9NKENUaI0= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings + + hash + + KoygslQ7+C06O61A0YHLMJPIhd8= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings + + hash + + Ed4oYGhilkGVvO6AshjBjzdE+7w= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/UI.strings + + hash + + Y50/iDsqGezjtBuqSlPo8jymMAc= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings + + hash + + 8OHVfUCzQp3y5Avt0qvL0KEijp8= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings + + hash + + nNEDjklKvB3EYDy3z/dKvk0Y3Sc= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings + + hash + + +2YIistydmlPjDts2u1ROqKtWqI= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings + + hash + + RbM1jidNxxT0GrCW5Bp4AJ2C10U= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings + + hash + + v+qEVshU1lPCEIX6p/5VNVvHCsE= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings + + hash + + XSewfIvou+2vfPzfd4L1JobLejU= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings + + hash + + j/ZhhE8EhAk/Lumf0d8hAl0mnM0= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings + + hash + + KhJ/QqRfNp4OZfzpif4GtcBF8bI= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings + + hash + + xDMWYimFFDfSHhe2YZpdtrl2g8k= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings + + hash + + uwWBmqf4ftnCEhc6CREp8ByROW4= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings + + hash + + NyXHmGW4hA/Eauh4ij9O5S5WhTA= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings + + hash + + YZpZdbu3r3xtH/jvKMalDSa3lOc= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings + + hash + + yqehLrthKrrux3wlT4BXD2o86VM= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings + + hash + + 6OMfwEOtzCuZV03uZytGep2fVcM= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings + + hash + + K6FfGb4sRyZ+8fUCnq80qKRGipc= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings + + hash + + jdPps229/rIXz+/ddHNG9FuKBhQ= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings + + hash + + fbM6TjAWhkqwQRqlFgXqxwrx+8k= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings + + hash + + 5JKfMEQAm3AUcBKlsob0yfJRkQk= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings + + hash + + 01ji1w1oANjR7h5TRr6cBlyaRGo= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings + + hash + + ZPLrICgFyE180EQFQQsAPW2T0LY= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings + + hash + + Ke55XO9cpqEQhKUHTr3HEvi0aUM= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings + + hash + + rfmjmvw733cPOhxZ0RizNQfXkSE= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings + + hash + + awJpWTrrqH31sd1t1ndiEy4cN/A= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/UI.strings + + hash + + QMaBIt1A8kjNOstov8L0lchT5Ec= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings + + hash + + 5J5E4i04UUqsWy3SQZN1zcKIZaQ= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings + + hash + + 55QLf0o5XG8IWfXbQ6KvFWToA+4= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings + + hash + + hfdFuAQLTfdHleeMkh4YCtlcNBY= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings + + hash + + R49azaTbZXexzZ4fO2KAO8IQIW4= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings + + hash + + B3OiNtJOoqFlNs77EeQh3/YlwiU= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings + + hash + + athEoNydnFVAkLxqKvlUTv5EfZg= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings + + hash + + 6aHDe64C6X+IcTDg3C39b+SM9Ls= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings + + hash + + InQh2yXFC6brp+xf2gtnVDZtsuY= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings + + hash + + 7NuRLJG/PUbRlsl/6dZTfboVNfQ= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings + + hash + + hBHKqa7nicnE6j15W8iBNQQdsws= + + optional + + + PIAWireguard_PIAWireguard.bundle/Info.plist + + /Sr7lQ3v9dlVi0s0lsUfQz9dK84= + + PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem + + 3qHvNikZqOiKtbZEW5+oygpFyfw= + + PIAWireguard_PIAWireguard.bundle/PIA.der + + HjU73bSJKXFVdCTqzHVin0iWAak= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory + + 1goWa+U5od4AnpP1zIi6N43ps+k= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements + + OnX22wWFKRSOFN1+obRynMCeyXM= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 + + ae4UnuV7lDFjF1toM8Tj2NbLvS4= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources + + G9y6xZfvG8s3gN1rZw4IpRPNIIc= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature + + 2jmj7l5rSw0yVb/vlWAYkK/YBwk= + + + files2 + + PIALibrary_PIALibrary.bundle/Assets.car + + hash2 + + z2oHVz8/itmR3oqHY51lv6NTMX9epuIIiBsUG+B3f3M= + + + PIALibrary_PIALibrary.bundle/Info.plist + + hash2 + + WFu/u2EPoebomnmaiyenOb8Mi4SrKw4owMy0mxtgPuY= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + hash2 + + EHhu+ZyC8bLdGTREBf6He41YqGou0HpQDQ4u1t+B67c= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib + + hash2 + + Rr/ex+JnT00WjY8BTVZWRNqz/GfU4jaR3v03FmrukIA= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + hash2 + + fkNfOkKA9R7NGpPPFiVhuYQ2+AdSVeR9osgZyyAms58= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib + + hash2 + + hDcEgabY8XWIV+bMHjY9T2LEXhXGYAjSsL1LyHygu1A= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist + + hash2 + + +ULlbQDKRqZAgLPRQ4aWV271svAlSIpTvPj8fAxklSA= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + hash2 + + vqbeJEql0Jgydj1T24xy6xJbrXkBGPmYusMqnTCSGcM= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + hash2 + + 28vreA7cNtWCBn0Hh2oGxsleKe0mqFxApasYvvlSWTo= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib + + hash2 + + FLZ/2WLEaK53aWKIJqX9T7ltNA15ERKTr7oZHeg14vU= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib + + hash2 + + 7XhIk/s4X/sIr5xEWP1PVGI7EV+vDS5HktrZ/OskXUk= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + hash2 + + N91d6/YhJJHCGX6EQSKWaoeSLBzL4sitnyKgo7IerzU= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + hash2 + + LmfITndcyawR5vC3q1+ZA3Tmezvc/H/UOm9eNi8rkXQ= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + hash2 + + cxj3iSMzDtgAEjJCn2Kh4wOxq643eP+NVKmuyRy4ScE= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + hash2 + + +pb1yeNeVETkzR3D7bHHd7b/7ckHANG2FYkou4fexeA= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + hash2 + + LcuEIHcg/ABNnzlBcFJUh1QnZG6OeeODUinCRME6gVM= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + hash2 + + 2sqAv9sKlmNLJyLvObb9ssgf6q3St0BYeyc41iKo10w= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist + + hash2 + + Y3Hpojl68zniB+aUL9PZXEVKtWuzsnlbS5/xAZKFhAo= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + hash2 + + rvJVcZPH3KzWKHiwzq/TcFc5ZloThq9gqavWaC6uX0s= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + hash2 + + 7V3P3q8VYMDAWwvrjqD85I4/kwFbGlegJ76JkMn8sDc= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + hash2 + + ZXVhR7A3IzlBTiK3AT8wLUDQeJhM59ywT6AJJWSHNuE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + hash2 + + gE07Q/56h7roPAuaRZhMhxJ+wNhM0gvRduQ2/Him9z8= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory + + hash2 + + okxh/GX6INtaXI5mCHxoHTTaQyHkvI6ouJ+gLzrnNDE= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements + + hash2 + + mHkgkE6rZQ51eIwFSqCwUk5qgL/HGqMt+NI3phdD+YY= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 + + hash2 + + lLcvw56pfEheqGNbi4m/Vp+O5ghlDPZzLW3I4aJ+Y/o= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources + + hash2 + + klaP6QnT3PPiOIqDEsVyy6EZJohkwril3bMp1OxL7PA= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature + + hash2 + + 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= + + + PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings + + hash2 + + /PdaPdFVdwwWy0WMwLSdWCQv9CkI1tpm2JyG/6Tmn9M= + + optional + + + PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings + + hash2 + + YhKnZ6a5ITfwAgnv/6Cd1x+TPQ067/rO+K+rWNEzD6w= + + optional + + + PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings + + hash2 + + S1/lODt2iX9EyVMvBt0dsAV6rYE8BdXAlCaTa1+HTsw= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings + + hash2 + + +bSgSn+Mt62wraeSALDwHwkp4db5Q4ig2thAObbQPnc= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/UI.strings + + hash2 + + doJ3NS9+wFy5hCKe75hwGTA8tafBSrCQJnnrwcghQQs= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings + + hash2 + + udZzYVGokipS7z20EPQUqoeoTxmet5LGclYicXo/Qzc= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings + + hash2 + + 3qf/FrW+/u8t/lO9wA/+NtfCBtCJ1WguXGz2uvwUoc0= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/UI.strings + + hash2 + + OqXvZaKPjVRbECIamvYeVtO1k5SXy41xBrfoDBODJzU= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings + + hash2 + + /RCU9b12hOYxRv0uKqNRMyGNoOs2qGmTkLw0Js7xFcQ= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings + + hash2 + + eTcLQYTr4H9oZFv0rxYaq3gQ+WhpLjFnSyzwaOIiehc= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/UI.strings + + hash2 + + 2LmfTdHJMvlivEZbaU9xSJAAnvlpBpvBa+WumfJ+Zbs= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings + + hash2 + + oAZWhsRhLpQkW9ZhuKf4MOb41w5Y8MZPZx3S0NMM5tk= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings + + hash2 + + nI1MegvByIjofRyKN8F43cuCTWoXr5uIExtoQ3BK6NM= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings + + hash2 + + a8Vp2K22QfOvNgn1DCjRhoTHkZVdwywOmftje9rC42Y= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings + + hash2 + + mxe8YvU0Z6ToCEE2d86cOJNrmOVz8cRCJpBzDQWLVWc= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings + + hash2 + + QqrxBLWpNYv5rrqBFN8BLC6LNXUmQVa74Gl+0ksKBZU= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings + + hash2 + + Pv8eZpPXvR5mqm53bwD8agrzEaWy3xj6YdWgIOflm+M= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings + + hash2 + + xyVMkl7jhNBZ/vN0ZFmM2FlY8ovTdbitINQqEgRyqks= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings + + hash2 + + VlWjS5dJ4UNfaNhHqlxeKfkECiko5YzTss4+zOmzYJ4= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/UI.strings + + hash2 + + y2JDFhY4F9hvHbr4F4pF6PrFuy4JUyVFpMw8BcbSBY4= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings + + hash2 + + lu+ZwHtxRo9m+9fmCbojh8YbdagKuR6eYwXH/O4QNHo= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings + + hash2 + + bDq3nM4T1ut8Ts8+QYkxdWNGRu+//zSf189mi3aRlQ8= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings + + hash2 + + YaeZ3JgOA+qIusYRqxxG6pwBkrFim1rw7qTyLnl060I= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings + + hash2 + + Xq2cl5IrUxxaYjKRRxrCcWp8u2KzQtjBAPMG2ywwICA= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings + + hash2 + + tGa6ibOVYp6N7/L++jdOleoT9KE1QQ1PK1rhzpVOKDQ= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings + + hash2 + + QIUwyVItXRoQKXGmgHFFotXmiOSE9JxkZlaoE2IHX+8= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings + + hash2 + + weQQxyn+b2SpWKeGAvJqE/ii7MCRaDRxNADg8r9TvYI= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings + + hash2 + + RnLEv00iw5lOIGL/XJzJU1ShBwn9hBnC4hNhikuyhA4= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings + + hash2 + + CbdEeBsje8P4+h3x6IQ57ZROUQ898FBunnH3ZY69DnQ= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings + + hash2 + + 3l4+0NbmewoK9l0/qdkIGPcqqrLIRM5eOrwPHGkUEy0= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings + + hash2 + + VfV2uL8OKA5ZiR3yiHFT65ZEHaCbkn35Yo+ur18Bqxw= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings + + hash2 + + 69DUk8Zeh5SReiVA+Wk9iHozzU98pp8V8uFeG+EA+A0= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings + + hash2 + + LHqIVFxiS7xOGRDl+Mc94nzpdWHZpV7V+YNrcO3F6rw= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings + + hash2 + + me1r0CSvQxGrjhri1zbZY30vF6XWxdoV5q/XNHlGVhs= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings + + hash2 + + frs+aVxqmI1A7qNQ3lTqmaN+e68SScT1D6TutOPSHFs= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings + + hash2 + + xQJW7uzg6y9kJf1gLZnCM9oO+0wQ84AayU+o+TV5Y2I= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings + + hash2 + + MnV7VMLXWFm/KNE5a8UHkxR04f0OznpqoK1+9hyw8zY= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings + + hash2 + + DxvjdPIJCkbOywZjS5+ayQkGKWHlrGcquTxizAdezyg= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings + + hash2 + + LDC5bZkG2h8AgTQLoL1yMj6JJA/ir2Qs9YoX0A27QLc= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings + + hash2 + + WWOM/zJIvlgQASAWOk/VrhJ76xkmJSNIM383qyAebmY= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings + + hash2 + + oSkpUWDyzNoWL+/tE+JqlzA0l5XGRGrg0sa5Gvpc4eA= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings + + hash2 + + NeG7RvpFs7aBDoclE4CeSnfGf9AS7tGvjGr/m1zT3eY= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings + + hash2 + + buuAYnSRdzIW7wnFAfyIoc2xNnPeH6VmMpaTl1UnDcI= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/UI.strings + + hash2 + + 86j7ej1K8vjK2Wc+4VvI8COo0F5VNrFgab6jFb52UQM= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings + + hash2 + + CWB5kJ7tdPh65LpMEk7ON91tZXYPjCLHG3+KYt/Wor8= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings + + hash2 + + J7rTcADNQWVMdE7ToyJl5ztWFP7nS0LpgiIcVb4D/H8= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings + + hash2 + + mn9KO/anRw5JkawqXZT06MvC8pSCiTjPxNb+c3RrZ1I= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings + + hash2 + + 3U8T+edoinqQskEd4Y8vg0sVEFsjDRp4YCrhcTIq0Nw= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings + + hash2 + + 92+yGo0u+BgXiVmoYH9vE1wxCXffUp20Eb5V8JkLJDU= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings + + hash2 + + iDsYoUTxx8POedODQmaipEBJukmHm0klpri/JSYxzCg= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings + + hash2 + + NtHmRVKzAicr7H8AVAqK8Bni236Z2cMnLjdcG/U7T6M= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings + + hash2 + + ajON8rkioyflp0u9oIDFniyq4zryBG0tC/51c7OOzbY= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings + + hash2 + + IvX18xiU0gageVb9uJLXqnoj5htrqNqSWI1LCqnTWY0= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings + + hash2 + + E7PBBBbQdDJESlMtJW1vcQ17At7XbJBTHK0Mbm0eyU0= + + optional + + + PIAWireguard_PIAWireguard.bundle/Info.plist + + hash2 + + mwC94dBByVRThcNBnzQ+IGHCLsHQKv9SdkUi4cOLyI4= + + + PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem + + hash2 + + Mumx0UM+qXYU8qFMbjWOP1fAVwzJ9rLugSaZumlsZqs= + + + PIAWireguard_PIAWireguard.bundle/PIA.der + + hash2 + + H9JWWEVuqzBB+6d8zTmKuBJO3MG4svwdVf32sbv8nXA= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory + + hash2 + + 0YGO8yzUacVLcwaChXyFEDV700SjEoA3y4jHNuxE/nQ= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements + + hash2 + + mHkgkE6rZQ51eIwFSqCwUk5qgL/HGqMt+NI3phdD+YY= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 + + hash2 + + tlUOZy9wXXkJrqlFG78GXGAwhg6PtVrzl/M9S9NNm64= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources + + hash2 + + JoxbI6Yk1SD3A2j4qcD82qxRn61PU0HoJwlTobmuafE= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature + + hash2 + + 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/Info.plist b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/Info.plist new file mode 100644 index 000000000..02c97d6a9 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/Info.plist differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIA VPN WG Tunnel b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIA VPN WG Tunnel new file mode 100755 index 000000000..9a0804cc3 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIA VPN WG Tunnel differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Assets.car b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Assets.car new file mode 100644 index 000000000..25f8a3020 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Assets.car differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Info.plist b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Info.plist new file mode 100644 index 000000000..0896d6b6f Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Info.plist differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib new file mode 100644 index 000000000..782e63cc6 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib new file mode 100644 index 000000000..8232ab814 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib new file mode 100644 index 000000000..b7fc0e162 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib new file mode 100644 index 000000000..50dcfb5e7 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist new file mode 100644 index 000000000..fb8201739 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib new file mode 100644 index 000000000..c2c4aa7ad Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib new file mode 100644 index 000000000..d8a9d70a5 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib new file mode 100644 index 000000000..8ba9b88b5 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib new file mode 100644 index 000000000..64cc2e51b Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib new file mode 100644 index 000000000..17e8c708d Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib new file mode 100644 index 000000000..4a92bd1d6 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib new file mode 100644 index 000000000..5000c5c1e Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib new file mode 100644 index 000000000..bbd696c11 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib new file mode 100644 index 000000000..3ff6637ef Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib new file mode 100644 index 000000000..9087e9150 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..e7dd91219 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib new file mode 100644 index 000000000..e7dd91219 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist new file mode 100644 index 000000000..a6ffe0e5d Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib new file mode 100644 index 000000000..0328b5682 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib new file mode 100644 index 000000000..f984c8279 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..85c0f3668 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib new file mode 100644 index 000000000..85c0f3668 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..f871a40b0 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib new file mode 100644 index 000000000..f871a40b0 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..71abc0b03 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib new file mode 100644 index 000000000..71abc0b03 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..32df7a32a Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib new file mode 100644 index 000000000..32df7a32a Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib new file mode 100644 index 000000000..87eb0e1cc Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib new file mode 100644 index 000000000..87eb0e1cc Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib new file mode 100644 index 000000000..fba5e5b84 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib new file mode 100644 index 000000000..fba5e5b84 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib new file mode 100644 index 000000000..3a454f116 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib new file mode 100644 index 000000000..3a454f116 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib new file mode 100644 index 000000000..03629a06f Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib new file mode 100644 index 000000000..03629a06f Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib new file mode 100644 index 000000000..f2476efe7 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib new file mode 100644 index 000000000..f2476efe7 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib new file mode 100644 index 000000000..76a131359 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib new file mode 100644 index 000000000..76a131359 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib new file mode 100644 index 000000000..4cbd2e982 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib new file mode 100644 index 000000000..e16ab5e4f Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib new file mode 100644 index 000000000..3496a4bbf Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib new file mode 100644 index 000000000..3496a4bbf Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib new file mode 100644 index 000000000..fcfccf837 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib new file mode 100644 index 000000000..fcfccf837 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory new file mode 100644 index 000000000..37d89a56f Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements new file mode 100644 index 000000000..dbf9d6144 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 new file mode 100644 index 000000000..b99f9a94a Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources new file mode 100644 index 000000000..93086328a --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources @@ -0,0 +1,1991 @@ + + + + + files + + Assets.car + + 8h6Hyf4U9/+JlpRmAN3vBaPEjrw= + + Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + dytHgVNc10hWhKQW+WIDasbWdTU= + + Signup.storyboardc/ConfirmVPNPlanViewController.nib + + OVb1ASokoqm9FsqgYqS4ykOLvTk= + + Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + qEnPzvZ7YJ2malb9v8b6uU1qRtI= + + Signup.storyboardc/GDPRViewController.nib + + BnH89TJFPy09hwlepgmy1qX8w5I= + + Signup.storyboardc/Info.plist + + tvSnglTgEmfEVDs4Pqzq89zCWdk= + + Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + htQTSxHbapTjr/KU4MZ+BReh+fg= + + Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + CJa19sBIiRCsSpkmvlAK9WVgIUc= + + Signup.storyboardc/ShareDataInformationViewController.nib + + DClrKMNBhP7R57XPbVZNLZEkhHY= + + Signup.storyboardc/SignupSuccessViewController.nib + + RII82MT1u8xiVhoF6z8GAPWRauw= + + Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + YpRMevT/Hk92B7qxIoBZNubmhVo= + + Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + bJ8pWQoqUwPJh2R449Z5iB80fgw= + + Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + XIT4vTE0sbcaxPw4Ukcc10AudMU= + + Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + 8QYAr5CSJVq9J2M/WNeKrHxyH4k= + + Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + /KugdZ7rq/us89d7xS8Y4W80uoE= + + Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + lAQN56rjGXobwkMhOfbs34FT+S8= + + Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + Welcome.storyboardc/Info.plist + + /pYtZWavELI0+6nEkTUa0WNFSew= + + Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + QLgeyu0ZVc/lDmyITQfrBSRT2Hk= + + Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + gA8eOIpUQd1BEBgO/w9hDFS+JxU= + + Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + Welcome.storyboardc/LoginViewController.nib/runtime.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + GzhYGB3AyZ0wytBn61POuwdsJ7E= + + Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + sQtUseVfpjT4CFtCBgvBwDjWfQA= + + Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + ar.lproj/Signup.strings + + hash + + KDACaW+muq3Q7S2KFi/tSoBrOA0= + + optional + + + ar.lproj/UI.strings + + hash + + q69blyRGQI14B9CBKT9Rsw4dq0k= + + optional + + + ar.lproj/Welcome.strings + + hash + + BkACZwewt5pWHuYeiW8u/ttymCg= + + optional + + + da.lproj/Signup.strings + + hash + + ImqHeuQyhd4vbb7tX6gDpc0Uws4= + + optional + + + da.lproj/UI.strings + + hash + + JEB6TYMiWHIJ3Fwzv9hwS3X5B9c= + + optional + + + da.lproj/Welcome.strings + + hash + + 0U+OaxIpF3m54GcZw6Rj0FT9IQU= + + optional + + + de.lproj/Signup.strings + + hash + + ULQLCKJ1Tkx5LYNqw+wZAPpz+fc= + + optional + + + de.lproj/UI.strings + + hash + + 1964G9tW/vLUljfWDybLqmj8ovo= + + optional + + + de.lproj/Welcome.strings + + hash + + j/jLkt7lT5WaqzpSmS2HeZ2YT7g= + + optional + + + en.lproj/Signup.strings + + hash + + EZ9QZ7PSibfcWSeEETK4rR/PkKE= + + optional + + + en.lproj/UI.strings + + hash + + 8v4J37YS+jZq3LBvpRfFdfrmOjo= + + optional + + + en.lproj/Welcome.strings + + hash + + BwdYyKtC03avQBNFX31HfqSElzI= + + optional + + + es-MX.lproj/Signup.strings + + hash + + /cuvVUGtYOlubi9pgRpN8GF6eaQ= + + optional + + + es-MX.lproj/UI.strings + + hash + + iiP5bcCQB5ClycQCkVGeHIMUAks= + + optional + + + es-MX.lproj/Welcome.strings + + hash + + lx4/QzIqPJcVTvU4PUA9DuA+iR0= + + optional + + + fr.lproj/Signup.strings + + hash + + vRPh7xNvA8CBlDbvqId98Ppaol4= + + optional + + + fr.lproj/UI.strings + + hash + + IbgvE2UN4PxyRd+exu9NKENUaI0= + + optional + + + fr.lproj/Welcome.strings + + hash + + KoygslQ7+C06O61A0YHLMJPIhd8= + + optional + + + it.lproj/Signup.strings + + hash + + Ed4oYGhilkGVvO6AshjBjzdE+7w= + + optional + + + it.lproj/UI.strings + + hash + + Y50/iDsqGezjtBuqSlPo8jymMAc= + + optional + + + it.lproj/Welcome.strings + + hash + + 8OHVfUCzQp3y5Avt0qvL0KEijp8= + + optional + + + ja.lproj/Signup.strings + + hash + + nNEDjklKvB3EYDy3z/dKvk0Y3Sc= + + optional + + + ja.lproj/UI.strings + + hash + + +2YIistydmlPjDts2u1ROqKtWqI= + + optional + + + ja.lproj/Welcome.strings + + hash + + RbM1jidNxxT0GrCW5Bp4AJ2C10U= + + optional + + + ko.lproj/Signup.strings + + hash + + v+qEVshU1lPCEIX6p/5VNVvHCsE= + + optional + + + ko.lproj/UI.strings + + hash + + XSewfIvou+2vfPzfd4L1JobLejU= + + optional + + + ko.lproj/Welcome.strings + + hash + + j/ZhhE8EhAk/Lumf0d8hAl0mnM0= + + optional + + + nb.lproj/Signup.strings + + hash + + KhJ/QqRfNp4OZfzpif4GtcBF8bI= + + optional + + + nb.lproj/UI.strings + + hash + + xDMWYimFFDfSHhe2YZpdtrl2g8k= + + optional + + + nb.lproj/Welcome.strings + + hash + + uwWBmqf4ftnCEhc6CREp8ByROW4= + + optional + + + nl.lproj/Signup.strings + + hash + + NyXHmGW4hA/Eauh4ij9O5S5WhTA= + + optional + + + nl.lproj/UI.strings + + hash + + YZpZdbu3r3xtH/jvKMalDSa3lOc= + + optional + + + nl.lproj/Welcome.strings + + hash + + yqehLrthKrrux3wlT4BXD2o86VM= + + optional + + + pl.lproj/Signup.strings + + hash + + 6OMfwEOtzCuZV03uZytGep2fVcM= + + optional + + + pl.lproj/UI.strings + + hash + + K6FfGb4sRyZ+8fUCnq80qKRGipc= + + optional + + + pl.lproj/Welcome.strings + + hash + + jdPps229/rIXz+/ddHNG9FuKBhQ= + + optional + + + pt-BR.lproj/Signup.strings + + hash + + fbM6TjAWhkqwQRqlFgXqxwrx+8k= + + optional + + + pt-BR.lproj/UI.strings + + hash + + 5JKfMEQAm3AUcBKlsob0yfJRkQk= + + optional + + + pt-BR.lproj/Welcome.strings + + hash + + 01ji1w1oANjR7h5TRr6cBlyaRGo= + + optional + + + ru.lproj/Signup.strings + + hash + + ZPLrICgFyE180EQFQQsAPW2T0LY= + + optional + + + ru.lproj/UI.strings + + hash + + Ke55XO9cpqEQhKUHTr3HEvi0aUM= + + optional + + + ru.lproj/Welcome.strings + + hash + + rfmjmvw733cPOhxZ0RizNQfXkSE= + + optional + + + th.lproj/Signup.strings + + hash + + awJpWTrrqH31sd1t1ndiEy4cN/A= + + optional + + + th.lproj/UI.strings + + hash + + QMaBIt1A8kjNOstov8L0lchT5Ec= + + optional + + + th.lproj/Welcome.strings + + hash + + 5J5E4i04UUqsWy3SQZN1zcKIZaQ= + + optional + + + tr.lproj/Signup.strings + + hash + + 55QLf0o5XG8IWfXbQ6KvFWToA+4= + + optional + + + tr.lproj/UI.strings + + hash + + hfdFuAQLTfdHleeMkh4YCtlcNBY= + + optional + + + tr.lproj/Welcome.strings + + hash + + R49azaTbZXexzZ4fO2KAO8IQIW4= + + optional + + + zh-Hans.lproj/Signup.strings + + hash + + B3OiNtJOoqFlNs77EeQh3/YlwiU= + + optional + + + zh-Hans.lproj/UI.strings + + hash + + athEoNydnFVAkLxqKvlUTv5EfZg= + + optional + + + zh-Hans.lproj/Welcome.strings + + hash + + 6aHDe64C6X+IcTDg3C39b+SM9Ls= + + optional + + + zh-Hant.lproj/Signup.strings + + hash + + InQh2yXFC6brp+xf2gtnVDZtsuY= + + optional + + + zh-Hant.lproj/UI.strings + + hash + + 7NuRLJG/PUbRlsl/6dZTfboVNfQ= + + optional + + + zh-Hant.lproj/Welcome.strings + + hash + + hBHKqa7nicnE6j15W8iBNQQdsws= + + optional + + + + files2 + + Assets.car + + hash + + 8h6Hyf4U9/+JlpRmAN3vBaPEjrw= + + hash2 + + z2oHVz8/itmR3oqHY51lv6NTMX9epuIIiBsUG+B3f3M= + + + Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + hash + + dytHgVNc10hWhKQW+WIDasbWdTU= + + hash2 + + EHhu+ZyC8bLdGTREBf6He41YqGou0HpQDQ4u1t+B67c= + + + Signup.storyboardc/ConfirmVPNPlanViewController.nib + + hash + + OVb1ASokoqm9FsqgYqS4ykOLvTk= + + hash2 + + Rr/ex+JnT00WjY8BTVZWRNqz/GfU4jaR3v03FmrukIA= + + + Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + hash + + qEnPzvZ7YJ2malb9v8b6uU1qRtI= + + hash2 + + fkNfOkKA9R7NGpPPFiVhuYQ2+AdSVeR9osgZyyAms58= + + + Signup.storyboardc/GDPRViewController.nib + + hash + + BnH89TJFPy09hwlepgmy1qX8w5I= + + hash2 + + hDcEgabY8XWIV+bMHjY9T2LEXhXGYAjSsL1LyHygu1A= + + + Signup.storyboardc/Info.plist + + hash + + tvSnglTgEmfEVDs4Pqzq89zCWdk= + + hash2 + + +ULlbQDKRqZAgLPRQ4aWV271svAlSIpTvPj8fAxklSA= + + + Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + hash + + htQTSxHbapTjr/KU4MZ+BReh+fg= + + hash2 + + vqbeJEql0Jgydj1T24xy6xJbrXkBGPmYusMqnTCSGcM= + + + Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + hash + + CJa19sBIiRCsSpkmvlAK9WVgIUc= + + hash2 + + 28vreA7cNtWCBn0Hh2oGxsleKe0mqFxApasYvvlSWTo= + + + Signup.storyboardc/ShareDataInformationViewController.nib + + hash + + DClrKMNBhP7R57XPbVZNLZEkhHY= + + hash2 + + FLZ/2WLEaK53aWKIJqX9T7ltNA15ERKTr7oZHeg14vU= + + + Signup.storyboardc/SignupSuccessViewController.nib + + hash + + RII82MT1u8xiVhoF6z8GAPWRauw= + + hash2 + + 7XhIk/s4X/sIr5xEWP1PVGI7EV+vDS5HktrZ/OskXUk= + + + Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + hash + + YpRMevT/Hk92B7qxIoBZNubmhVo= + + hash2 + + N91d6/YhJJHCGX6EQSKWaoeSLBzL4sitnyKgo7IerzU= + + + Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + hash + + bJ8pWQoqUwPJh2R449Z5iB80fgw= + + hash2 + + LmfITndcyawR5vC3q1+ZA3Tmezvc/H/UOm9eNi8rkXQ= + + + Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + hash + + XIT4vTE0sbcaxPw4Ukcc10AudMU= + + hash2 + + cxj3iSMzDtgAEjJCn2Kh4wOxq643eP+NVKmuyRy4ScE= + + + Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + hash + + 8QYAr5CSJVq9J2M/WNeKrHxyH4k= + + hash2 + + +pb1yeNeVETkzR3D7bHHd7b/7ckHANG2FYkou4fexeA= + + + Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + hash + + /KugdZ7rq/us89d7xS8Y4W80uoE= + + hash2 + + LcuEIHcg/ABNnzlBcFJUh1QnZG6OeeODUinCRME6gVM= + + + Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + hash + + lAQN56rjGXobwkMhOfbs34FT+S8= + + hash2 + + 2sqAv9sKlmNLJyLvObb9ssgf6q3St0BYeyc41iKo10w= + + + Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + hash + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + hash + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + Welcome.storyboardc/Info.plist + + hash + + /pYtZWavELI0+6nEkTUa0WNFSew= + + hash2 + + Y3Hpojl68zniB+aUL9PZXEVKtWuzsnlbS5/xAZKFhAo= + + + Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + hash + + QLgeyu0ZVc/lDmyITQfrBSRT2Hk= + + hash2 + + rvJVcZPH3KzWKHiwzq/TcFc5ZloThq9gqavWaC6uX0s= + + + Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + hash + + gA8eOIpUQd1BEBgO/w9hDFS+JxU= + + hash2 + + 7V3P3q8VYMDAWwvrjqD85I4/kwFbGlegJ76JkMn8sDc= + + + Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + hash + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + Welcome.storyboardc/LoginViewController.nib/runtime.nib + + hash + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + hash + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + hash + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + hash + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + hash + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + hash + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + hash + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + hash + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + hash + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + hash + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + hash + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + hash + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + hash + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + hash + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + hash + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + hash + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + hash + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + hash + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + hash + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + hash + + GzhYGB3AyZ0wytBn61POuwdsJ7E= + + hash2 + + ZXVhR7A3IzlBTiK3AT8wLUDQeJhM59ywT6AJJWSHNuE= + + + Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + hash + + sQtUseVfpjT4CFtCBgvBwDjWfQA= + + hash2 + + gE07Q/56h7roPAuaRZhMhxJ+wNhM0gvRduQ2/Him9z8= + + + Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + hash + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + hash + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + hash + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + hash + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + ar.lproj/Signup.strings + + hash + + KDACaW+muq3Q7S2KFi/tSoBrOA0= + + hash2 + + /PdaPdFVdwwWy0WMwLSdWCQv9CkI1tpm2JyG/6Tmn9M= + + optional + + + ar.lproj/UI.strings + + hash + + q69blyRGQI14B9CBKT9Rsw4dq0k= + + hash2 + + YhKnZ6a5ITfwAgnv/6Cd1x+TPQ067/rO+K+rWNEzD6w= + + optional + + + ar.lproj/Welcome.strings + + hash + + BkACZwewt5pWHuYeiW8u/ttymCg= + + hash2 + + S1/lODt2iX9EyVMvBt0dsAV6rYE8BdXAlCaTa1+HTsw= + + optional + + + da.lproj/Signup.strings + + hash + + ImqHeuQyhd4vbb7tX6gDpc0Uws4= + + hash2 + + +bSgSn+Mt62wraeSALDwHwkp4db5Q4ig2thAObbQPnc= + + optional + + + da.lproj/UI.strings + + hash + + JEB6TYMiWHIJ3Fwzv9hwS3X5B9c= + + hash2 + + doJ3NS9+wFy5hCKe75hwGTA8tafBSrCQJnnrwcghQQs= + + optional + + + da.lproj/Welcome.strings + + hash + + 0U+OaxIpF3m54GcZw6Rj0FT9IQU= + + hash2 + + udZzYVGokipS7z20EPQUqoeoTxmet5LGclYicXo/Qzc= + + optional + + + de.lproj/Signup.strings + + hash + + ULQLCKJ1Tkx5LYNqw+wZAPpz+fc= + + hash2 + + 3qf/FrW+/u8t/lO9wA/+NtfCBtCJ1WguXGz2uvwUoc0= + + optional + + + de.lproj/UI.strings + + hash + + 1964G9tW/vLUljfWDybLqmj8ovo= + + hash2 + + OqXvZaKPjVRbECIamvYeVtO1k5SXy41xBrfoDBODJzU= + + optional + + + de.lproj/Welcome.strings + + hash + + j/jLkt7lT5WaqzpSmS2HeZ2YT7g= + + hash2 + + /RCU9b12hOYxRv0uKqNRMyGNoOs2qGmTkLw0Js7xFcQ= + + optional + + + en.lproj/Signup.strings + + hash + + EZ9QZ7PSibfcWSeEETK4rR/PkKE= + + hash2 + + eTcLQYTr4H9oZFv0rxYaq3gQ+WhpLjFnSyzwaOIiehc= + + optional + + + en.lproj/UI.strings + + hash + + 8v4J37YS+jZq3LBvpRfFdfrmOjo= + + hash2 + + 2LmfTdHJMvlivEZbaU9xSJAAnvlpBpvBa+WumfJ+Zbs= + + optional + + + en.lproj/Welcome.strings + + hash + + BwdYyKtC03avQBNFX31HfqSElzI= + + hash2 + + oAZWhsRhLpQkW9ZhuKf4MOb41w5Y8MZPZx3S0NMM5tk= + + optional + + + es-MX.lproj/Signup.strings + + hash + + /cuvVUGtYOlubi9pgRpN8GF6eaQ= + + hash2 + + nI1MegvByIjofRyKN8F43cuCTWoXr5uIExtoQ3BK6NM= + + optional + + + es-MX.lproj/UI.strings + + hash + + iiP5bcCQB5ClycQCkVGeHIMUAks= + + hash2 + + a8Vp2K22QfOvNgn1DCjRhoTHkZVdwywOmftje9rC42Y= + + optional + + + es-MX.lproj/Welcome.strings + + hash + + lx4/QzIqPJcVTvU4PUA9DuA+iR0= + + hash2 + + mxe8YvU0Z6ToCEE2d86cOJNrmOVz8cRCJpBzDQWLVWc= + + optional + + + fr.lproj/Signup.strings + + hash + + vRPh7xNvA8CBlDbvqId98Ppaol4= + + hash2 + + QqrxBLWpNYv5rrqBFN8BLC6LNXUmQVa74Gl+0ksKBZU= + + optional + + + fr.lproj/UI.strings + + hash + + IbgvE2UN4PxyRd+exu9NKENUaI0= + + hash2 + + Pv8eZpPXvR5mqm53bwD8agrzEaWy3xj6YdWgIOflm+M= + + optional + + + fr.lproj/Welcome.strings + + hash + + KoygslQ7+C06O61A0YHLMJPIhd8= + + hash2 + + xyVMkl7jhNBZ/vN0ZFmM2FlY8ovTdbitINQqEgRyqks= + + optional + + + it.lproj/Signup.strings + + hash + + Ed4oYGhilkGVvO6AshjBjzdE+7w= + + hash2 + + VlWjS5dJ4UNfaNhHqlxeKfkECiko5YzTss4+zOmzYJ4= + + optional + + + it.lproj/UI.strings + + hash + + Y50/iDsqGezjtBuqSlPo8jymMAc= + + hash2 + + y2JDFhY4F9hvHbr4F4pF6PrFuy4JUyVFpMw8BcbSBY4= + + optional + + + it.lproj/Welcome.strings + + hash + + 8OHVfUCzQp3y5Avt0qvL0KEijp8= + + hash2 + + lu+ZwHtxRo9m+9fmCbojh8YbdagKuR6eYwXH/O4QNHo= + + optional + + + ja.lproj/Signup.strings + + hash + + nNEDjklKvB3EYDy3z/dKvk0Y3Sc= + + hash2 + + bDq3nM4T1ut8Ts8+QYkxdWNGRu+//zSf189mi3aRlQ8= + + optional + + + ja.lproj/UI.strings + + hash + + +2YIistydmlPjDts2u1ROqKtWqI= + + hash2 + + YaeZ3JgOA+qIusYRqxxG6pwBkrFim1rw7qTyLnl060I= + + optional + + + ja.lproj/Welcome.strings + + hash + + RbM1jidNxxT0GrCW5Bp4AJ2C10U= + + hash2 + + Xq2cl5IrUxxaYjKRRxrCcWp8u2KzQtjBAPMG2ywwICA= + + optional + + + ko.lproj/Signup.strings + + hash + + v+qEVshU1lPCEIX6p/5VNVvHCsE= + + hash2 + + tGa6ibOVYp6N7/L++jdOleoT9KE1QQ1PK1rhzpVOKDQ= + + optional + + + ko.lproj/UI.strings + + hash + + XSewfIvou+2vfPzfd4L1JobLejU= + + hash2 + + QIUwyVItXRoQKXGmgHFFotXmiOSE9JxkZlaoE2IHX+8= + + optional + + + ko.lproj/Welcome.strings + + hash + + j/ZhhE8EhAk/Lumf0d8hAl0mnM0= + + hash2 + + weQQxyn+b2SpWKeGAvJqE/ii7MCRaDRxNADg8r9TvYI= + + optional + + + nb.lproj/Signup.strings + + hash + + KhJ/QqRfNp4OZfzpif4GtcBF8bI= + + hash2 + + RnLEv00iw5lOIGL/XJzJU1ShBwn9hBnC4hNhikuyhA4= + + optional + + + nb.lproj/UI.strings + + hash + + xDMWYimFFDfSHhe2YZpdtrl2g8k= + + hash2 + + CbdEeBsje8P4+h3x6IQ57ZROUQ898FBunnH3ZY69DnQ= + + optional + + + nb.lproj/Welcome.strings + + hash + + uwWBmqf4ftnCEhc6CREp8ByROW4= + + hash2 + + 3l4+0NbmewoK9l0/qdkIGPcqqrLIRM5eOrwPHGkUEy0= + + optional + + + nl.lproj/Signup.strings + + hash + + NyXHmGW4hA/Eauh4ij9O5S5WhTA= + + hash2 + + VfV2uL8OKA5ZiR3yiHFT65ZEHaCbkn35Yo+ur18Bqxw= + + optional + + + nl.lproj/UI.strings + + hash + + YZpZdbu3r3xtH/jvKMalDSa3lOc= + + hash2 + + 69DUk8Zeh5SReiVA+Wk9iHozzU98pp8V8uFeG+EA+A0= + + optional + + + nl.lproj/Welcome.strings + + hash + + yqehLrthKrrux3wlT4BXD2o86VM= + + hash2 + + LHqIVFxiS7xOGRDl+Mc94nzpdWHZpV7V+YNrcO3F6rw= + + optional + + + pl.lproj/Signup.strings + + hash + + 6OMfwEOtzCuZV03uZytGep2fVcM= + + hash2 + + me1r0CSvQxGrjhri1zbZY30vF6XWxdoV5q/XNHlGVhs= + + optional + + + pl.lproj/UI.strings + + hash + + K6FfGb4sRyZ+8fUCnq80qKRGipc= + + hash2 + + frs+aVxqmI1A7qNQ3lTqmaN+e68SScT1D6TutOPSHFs= + + optional + + + pl.lproj/Welcome.strings + + hash + + jdPps229/rIXz+/ddHNG9FuKBhQ= + + hash2 + + xQJW7uzg6y9kJf1gLZnCM9oO+0wQ84AayU+o+TV5Y2I= + + optional + + + pt-BR.lproj/Signup.strings + + hash + + fbM6TjAWhkqwQRqlFgXqxwrx+8k= + + hash2 + + MnV7VMLXWFm/KNE5a8UHkxR04f0OznpqoK1+9hyw8zY= + + optional + + + pt-BR.lproj/UI.strings + + hash + + 5JKfMEQAm3AUcBKlsob0yfJRkQk= + + hash2 + + DxvjdPIJCkbOywZjS5+ayQkGKWHlrGcquTxizAdezyg= + + optional + + + pt-BR.lproj/Welcome.strings + + hash + + 01ji1w1oANjR7h5TRr6cBlyaRGo= + + hash2 + + LDC5bZkG2h8AgTQLoL1yMj6JJA/ir2Qs9YoX0A27QLc= + + optional + + + ru.lproj/Signup.strings + + hash + + ZPLrICgFyE180EQFQQsAPW2T0LY= + + hash2 + + WWOM/zJIvlgQASAWOk/VrhJ76xkmJSNIM383qyAebmY= + + optional + + + ru.lproj/UI.strings + + hash + + Ke55XO9cpqEQhKUHTr3HEvi0aUM= + + hash2 + + oSkpUWDyzNoWL+/tE+JqlzA0l5XGRGrg0sa5Gvpc4eA= + + optional + + + ru.lproj/Welcome.strings + + hash + + rfmjmvw733cPOhxZ0RizNQfXkSE= + + hash2 + + NeG7RvpFs7aBDoclE4CeSnfGf9AS7tGvjGr/m1zT3eY= + + optional + + + th.lproj/Signup.strings + + hash + + awJpWTrrqH31sd1t1ndiEy4cN/A= + + hash2 + + buuAYnSRdzIW7wnFAfyIoc2xNnPeH6VmMpaTl1UnDcI= + + optional + + + th.lproj/UI.strings + + hash + + QMaBIt1A8kjNOstov8L0lchT5Ec= + + hash2 + + 86j7ej1K8vjK2Wc+4VvI8COo0F5VNrFgab6jFb52UQM= + + optional + + + th.lproj/Welcome.strings + + hash + + 5J5E4i04UUqsWy3SQZN1zcKIZaQ= + + hash2 + + CWB5kJ7tdPh65LpMEk7ON91tZXYPjCLHG3+KYt/Wor8= + + optional + + + tr.lproj/Signup.strings + + hash + + 55QLf0o5XG8IWfXbQ6KvFWToA+4= + + hash2 + + J7rTcADNQWVMdE7ToyJl5ztWFP7nS0LpgiIcVb4D/H8= + + optional + + + tr.lproj/UI.strings + + hash + + hfdFuAQLTfdHleeMkh4YCtlcNBY= + + hash2 + + mn9KO/anRw5JkawqXZT06MvC8pSCiTjPxNb+c3RrZ1I= + + optional + + + tr.lproj/Welcome.strings + + hash + + R49azaTbZXexzZ4fO2KAO8IQIW4= + + hash2 + + 3U8T+edoinqQskEd4Y8vg0sVEFsjDRp4YCrhcTIq0Nw= + + optional + + + zh-Hans.lproj/Signup.strings + + hash + + B3OiNtJOoqFlNs77EeQh3/YlwiU= + + hash2 + + 92+yGo0u+BgXiVmoYH9vE1wxCXffUp20Eb5V8JkLJDU= + + optional + + + zh-Hans.lproj/UI.strings + + hash + + athEoNydnFVAkLxqKvlUTv5EfZg= + + hash2 + + iDsYoUTxx8POedODQmaipEBJukmHm0klpri/JSYxzCg= + + optional + + + zh-Hans.lproj/Welcome.strings + + hash + + 6aHDe64C6X+IcTDg3C39b+SM9Ls= + + hash2 + + NtHmRVKzAicr7H8AVAqK8Bni236Z2cMnLjdcG/U7T6M= + + optional + + + zh-Hant.lproj/Signup.strings + + hash + + InQh2yXFC6brp+xf2gtnVDZtsuY= + + hash2 + + ajON8rkioyflp0u9oIDFniyq4zryBG0tC/51c7OOzbY= + + optional + + + zh-Hant.lproj/UI.strings + + hash + + 7NuRLJG/PUbRlsl/6dZTfboVNfQ= + + hash2 + + IvX18xiU0gageVb9uJLXqnoj5htrqNqSWI1LCqnTWY0= + + optional + + + zh-Hant.lproj/Welcome.strings + + hash + + hBHKqa7nicnE6j15W8iBNQQdsws= + + hash2 + + E7PBBBbQdDJESlMtJW1vcQ17At7XbJBTHK0Mbm0eyU0= + + optional + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature new file mode 100644 index 000000000..e69de29bb diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings new file mode 100644 index 000000000..ce7d9f39d --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "تأكيد التسجيل"; +"in_progress.message" = "جارٍ تأكيد عملية الشراء مع نظامنا. يمكن أن يستغرق ذلك لحظة لذلك انتظر قليلًا."; +"in_progress.redeem.message" = "جارٍ تأكيد رمز بطاقتك مع نظامنا. قد يستغرق ذلك بضع لحظات، انتظر قليلًا."; + +"success.title" = "تم الشراء"; +"success.message_format" = "شضكراً على اشتراكك معنا. لقد أرسلنا اسم المستخدم وكلمة المرور الخاصين بك إلى بريدك الإلكتروني %@"; +"success.redeem.title" = "تم استبدال البطاقة بنجاح"; +"success.redeem.message" = "ستصلك رسالة عبر البريد الإلكتروني تتضمن اسم المستخدم وكلمة المرور.\n\nتفاصيل تسجيل الدخول"; +"success.username.caption" = "اسم المستخدم"; +"success.password.caption" = "كلمة المرور"; +"success.submit" = "كيف تبدأ"; + +"failure.vc_title" = "فشل تسجيل الآن"; +"failure.title" = "فشل إنشاء الحساب"; +"failure.message" = "يتعذر علينا إنشاء حساب في الوقت الحالي. يرجى إعادة المحاولة لاحقًا. \n\nعند إعادة فتح التطبيق سيتم إعادة محاولة إنشاء حساب."; +"failure.purchase.sandbox.message" = "اشتراك الصندوق المحدد غير متاح في الإنتاج."; +"failure.redeem.invalid.title" = "رمز بطاقة غير صالح"; +"failure.redeem.invalid.message" = "يبدو أنك أدخلت رمز بطاقة غير صالح. يرجى إعادة المحاولة."; +"failure.redeem.claimed.title" = "تم استخدام هذه البطاقة بالفعل"; +"failure.redeem.claimed.message" = "يبدو أن هذه البطاقة استُخدمت في حساب آخر. حاول إدخال رمز جديد."; +"failure.submit" = "عودة"; + +"unreachable.vc_title" = "خطأ"; +"unreachable.title" = "أوبس!"; +"unreachable.message" = "لم يتم العثور على اتصال بالإنترنت. يرجى التأكد من اتصالك بالإنترنت وضغط زر إعادة المحاولة أدناه.\n\nيمكنك العودة إلى التطبيق في وقت لاحق لإنهاء العملية."; +"unreachable.submit" = "أعد المحاولة"; + +"purchase.uncredited.alert.message" = "لديك معاملات غير معتمدة. هل تريد استعادة تفاصيل حسابك؟"; +"purchase.uncredited.alert.button.cancel" = "إلغاء"; +"purchase.uncredited.alert.button.recover" = "استعادة الحساب"; + +"purchase.trials.intro" = "ابدأ تجربتك المجانية لمدة 7 ايام"; +"purchase.trials.price.after" = "ثم %@"; +"purchase.trials.money.back" = "ضمان استرداد المال لمدة 30 أيام"; +"purchase.trials.1year.protection" = "1 سنة من الخصوصية وحماية الهوية"; +"purchase.trials.anonymous" = "تصفح مجهول الهوية وإخفاء عنوان IP."; +"purchase.trials.devices" = "يدعم 10 أجهزة في المرة الواحدة"; +"purchase.trials.devices.description" = "احمي نفسك على ما يصل إلى 10 أجهزة في وقت واحد."; +"purchase.trials.region" = "اتصل بأي منطقة بسهولة"; +"purchase.trials.servers" = "أكثر من 3300 خادم في 32 دولة"; +"purchase.trials.start" = "ابدأ الاشتراك"; +"purchase.trials.all.plans" = "مشاهدة جميع الخطط المتاحة"; + +"purchase.subscribe.now" = "اشتراك الآن"; + +// WALKTHROUGH + +"walkthrough.action.next" = "التالي"; +"walkthrough.action.done" = "تم"; +"walkthrough.action.skip" = "تخطي"; + +"walkthrough.page.1.title" = "يدعم 10 أجهزة في المرة الواحدة"; +"walkthrough.page.1.description" = "احمي نفسك على ما يصل إلى 10 أجهزة في وقت واحد."; +"walkthrough.page.2.title" = "اتصل بأي منطقة بسهولة"; +"walkthrough.page.2.description" = "مع خوادم في جميع أنحاء العالم، أنت دائما تحت الحماية."; +"walkthrough.page.3.title" = "احمي نفسك من الإعلانات"; +"walkthrough.page.3.description" = "تمكين ميزة حظر المحتوى يمنع الإعلانات من الظهور في Safari."; + +"share.data.buttons.accept" = "قبول"; +"share.data.buttons.noThanks" = "لا، شكرًا"; +"share.data.buttons.readMore" = "قراءة المزيد"; +"share.data.text.title" = "يرجى مساعدتنا في تحسين خدمتنا"; +"share.data.text.description" = "لمساعدتنا في ضمان أداء اتصال خدمتنا، يمكنك مشاركة إحصائيات اتصالك معنا دون الكشف عن هويتك. لا تتضمن هذه التقارير أي معلومات محددة للشخصية."; +"share.data.text.footer" = "يمكنك دائمًا التحكم في ذلك من إعداداتك"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings new file mode 100644 index 000000000..d93d9b375 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "الإصدار %@ (%@)"; +"global.close" = "إغلاق"; +"global.ok" = "موافق"; +"global.cancel" = "إلغاء"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings new file mode 100644 index 000000000..75d5562b2 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "سجل الدخول إلى حسابك"; +"login.username.placeholder" = "اسم المستخدم (p1234567)"; +"login.password.placeholder" = "كلمة المرور"; +"login.submit" = "تسجيل الدخول"; +"login.restore.button" = "لم تحصل على تفاصيل الحساب؟"; +"login.error.title" = "تسجيل الدخول"; +"login.error.validation" = "يجب إدخال اسم المستخدم وكلمة المرور"; +"login.error.unauthorized" = "اسم المستخدم أو كلمة المرور غير صحيحة."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "تسجيل الدخول باستخدام إيصال الشراء"; +"login.magic.link.title" = "تسجيل الدخول باستخدام رابط البريد الإلكتروني السحري"; +"login.magic.link.response" = "يرجى إلقاء نظرة على بريدك الإلكتروني للحصول على رابط تسجيل الدخول."; +"login.magic.link.send" = "إرسال الرابط"; +"login.magic.link.invalid.email" = "البريد الإلكتروني غير صحيح. يرجى إعادة المحاولة."; + +"purchase.title" = "حدد خطة VPN"; +"purchase.subtitle" = "ضمان استرداد المال لمدة 7 أيام"; +"purchase.email.placeholder" = "البريد الإلكتروني"; +"purchase.continue" = "متابعة"; +"purchase.login.footer" = "لديك حساب بالفعل؟"; +"purchase.login.button" = "تسجيل الدخول"; +"purchase.error.title" = "شراء"; +"purchase.error.validation" = "يجب إدخال عنوان بريد إلكتروني."; +"purchase.error.connectivity.title" = "فشل الاتصال"; +"purchase.error.connectivity.description" = "لم نتمكن من الوصول إلى منفذ الإنترنت الخاص. ربما بسبب اتصال ضعيف بالإنترنت أو خدماتنا موقوفة في بلدك."; +"purchase.confirm.form.email" = "يرجى إدخال بريدك الإلكتروني"; +"purchase.confirm.plan" = "أنت تشتري الآن خطة %@"; +"purchase.email.why" = "نحتاج إلى بريدك الإلكتروني لإرسال اسم المستخدم وكلمة المرور."; +"purchase.submit" = "إرسال"; +"purchase.or" = "أو"; + +"upgrade.header" = "مرحبًا بعودتك!"; +"upgrade.title" = "لاستخدام Private Internet Access، تحتاج إلى تجديد اشتراكك."; +"upgrade.renew.now" = "تجديد الآن"; + + + +"redeem.title" = "استلم محتويات بطاقة هدية"; +"redeem.subtitle" = "أدخل بريدك الإلكتروني ورمز بطاقة الهدية أو بطاقة التجربة المكون من %lu خانات."; +"redeem.email.placeholder" = "البريد الإلكتروني"; +"redeem.submit" = "إرسال"; +"redeem.error.title" = "استلام"; +"redeem.error.code" = "يجب أن يتكون الرمز من %lu خانات رقمية."; +"redeem.error.allfields" = "يرجى كتابة بريدك الإلكتروني ورمز PIN الخاص بالبطاقة."; +"redeem.accessibility.back" = "عودة"; +"redeem.giftcard.placeholder" = "رمز PIN الخاص بالبطاقة."; + +"plan.monthly.title" = "شهريًا"; +"plan.yearly.title" = "سنويًا"; +"plan.yearly.detail_format" = "%@%@ في السنة"; +"plan.price_format" = "%@ / شهر"; +"plan.best_value" = "أفضل قيمة"; +"plan.accessibility.per_month" = "في الشهر"; + +"restore.title" = "استرداد الشراء غير المقيد في الحساب"; +"restore.subtitle" = "إذا اشتريت خطة من خلال هذا التطبيق ولم تصلك بيانات تسجيل دخولك، يمكنك إرسالها مرة أخرى من هنا. لن يتم تحصيل رسوم منك أثناء هذه العملية."; +"restore.email.placeholder" = "البريد الإلكتروني"; +"restore.submit" = "تأكيد"; + +"iap.error.message.unavailable" = "خوادم أبل غير متاحة حاليًا. يرجى إعادة المحاولة لاحقًا."; +"iap.error.title" = "خطأ"; + +"agreement.trials.title" = "شروط وأحكام الفترات التجريبية المجانية"; +"agreement.trials.message" = "سيتم تحصيل مبلغ الدفع من حساب Apple ID الخاص بك عند تأكيد الشراء. يتم تجديد الاشتراك تلقائيًا ما لم يتم إلغاؤه قبل نهاية الفترة الحالية بمدة 24 ساعة على الأقل. سيتم محاسبتك على التجديد خلال 24 ساعة قبل نهاية الفترة الحالية. يمكنك إدارة وإلغاء اشتراكاتك عن طريق الانتقال إلى إعدادات حسابك في متجر التطبيقات بعد الشراء.\n\nقد توفر بعض الاشتراكات المدفوعة فترة تجريبية مجانية قبل تحصيل المبلغ من طريقة الدفع. إذا قررت إلغاء الاشتراك من اشتراك مدفوع قبل البدء في تحصيل الرسوم من طريقة الدفع، قم بإلغاء الاشتراك قبل انتهاء الفترة التجريبية المجانية بمدة 24 ساعة على الأقل.\n\nلا يتم توفير التجارب المجانية إلا للمستخدمين الجدد فقط، وهي وفقًا لتقديرنا الخاص، وإذا حاولت التسجيل للحصول على فترة تجريبية مجانية إضافية، فستتم محاسبتك فورًا على رسوم الاشتراك القياسية.\n\nنحن نحتفظ بالحق في إلغاء الفترة التجريبية المجانية في أي وقت.\n\nسيتم مصادرة أي جزء غير مستخدم من الفترة التجريبية المجانية عند شراء اشتراك.\n\nيمثل التسجيل قبولًا لهذه الشروط والأحكام."; +"agreement.message" = "بعد انتهاء الـ 7 أيام الخاصة بالفترة التجريبية المجانية، يتم تجديد هذا الاشتراك تلقائيًا مقابل %@ ما لم يتم إلغاؤه قبل 24 ساعة على الأقل من نهاية الفترة التجريبية. ستتم محاسبة حساب Apple ID الخاص بك على رسوم التجديد في غضون 24 ساعة قبل نهاية الفترة التجريبية. يمكنك إدارة وإلغاء اشتراكاتك عن طريق الانتقال إلى إعدادات حسابك في App Store بعد الشراء. يقتصر عرض الفترة التجريبية لمدة 7 أيام على عرض فترة تجريبية واحد لمدة 7 أيام لكل مستخدم. أي جزء غير مستخدم من الفترة التجريبية المجانية، إذا تم عرضها، سيتم مصادرته عندما يشتري المستخدم اشتراكًا. تشمل جميع الأسعار ضرائب المبيعات المحلية المطبقة.\n\nيعتبر الاشتراك بمثابة قبول $1 و$2."; +"agreement.trials.yearly.plan" = "سنة"; +"agreement.trials.monthly.plan" = "شهر"; + +"agreement.message.tos" = "شروط الخدمة"; +"agreement.message.privacy" = "سياسة الخصوصية"; + +"getstarted.buttons.buyaccount" = "شراء حساب"; + +"gdpr.collect.data.title" = "المعلومات الشخصية التي نجمعها"; +"gdpr.collect.data.description" = "عنوان البريد الإلكتروني لأغراض إدارة الحساب والحماية من إساءة الاستخدام."; +"gdpr.usage.data.title" = "استخدامات المعلومات الشخصية التي نجمعها"; +"gdpr.usage.data.description" = "يتم استخدام عنوان البريد الإلكتروني لإرسال معلومات الاشتراك وتأكيد الدفع ومراسلات العملاء والعروض الترويجية الخاصة بـ Private Internet Access فقط."; +"gdpr.accept.button.title" = "موافق ومتابعة"; + +"update.account.email.error" = "تعذَّر تعديل البريد الإلكتروني للحساب"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings new file mode 100644 index 000000000..44c000115 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Bekræft tilmelding"; +"in_progress.message" = "Vi bekræfter dit køb i vores system. Det kan tage et øjeblik, så bliv her venligst."; +"in_progress.redeem.message" = "Vi bekræfter din kort-pinkode i vores system. Det kan tage et øjeblik, så bliv her venligst."; + +"success.title" = "Køb fuldført"; +"success.message_format" = "Tak fordi du tilmeldte dig hos os. Vi har sendt dit brugernavn og kodeord til din e-mailadresse %@"; +"success.redeem.title" = "Kort indløst med succes"; +"success.redeem.message" = "Du modtager snart en e-mail med dit brugernavn og adgangskode.\n\nDine loginoplysninger"; +"success.username.caption" = "Brugernavn"; +"success.password.caption" = "Kodeord"; +"success.submit" = "Kom i gang"; + +"failure.vc_title" = "Tilmelding mislykkedes"; +"failure.title" = "Kunne ikke oprette konto"; +"failure.message" = "Vi kan ikke oprette en konto på nuværende tidspunkt. Prøv igen senere.\n\nGenåbning af appen vil genoptage forsøget på at oprette en konto."; +"failure.purchase.sandbox.message" = "Det valgte sandbox-abonnement er ikke tilgængeligt i produktionen."; +"failure.redeem.invalid.title" = "Ugyldig kort-pinkode"; +"failure.redeem.invalid.message" = "Det ser ud til, at du har indtastet en ugyldig kort-pinkode. Prøv igen."; +"failure.redeem.claimed.title" = "Kort allerede taget"; +"failure.redeem.claimed.message" = "Det ser ud til, at dette kort allerede er taget af en anden konto. Prøv at indtaste en anden pinkode."; +"failure.submit" = "GÅ TILBAGE"; + +"unreachable.vc_title" = "Fejl"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Ingen internetforbindelse fundet. Bekræft venligst, at du har en internetforbindelse, og tryk på \"prøv igen\" herunder.\n\nDu kan vende tilbage til appen senere for at afslutte processen."; +"unreachable.submit" = "PRØV IGEN"; + +"purchase.uncredited.alert.message" = "Du har ukrediterede transaktioner. Vil du gendanne dine kontooplysninger?"; +"purchase.uncredited.alert.button.cancel" = "Annuller"; +"purchase.uncredited.alert.button.recover" = "Gendan konto"; + +"purchase.trials.intro" = "Start din 7-dages gratis prøveperiode"; +"purchase.trials.price.after" = "Derefter %@"; +"purchase.trials.money.back" = "30-dages pengene tilbage garanti"; +"purchase.trials.1year.protection" = "1 års beskyttelse af personlige oplysninger og identitet"; +"purchase.trials.anonymous" = "Gennemse anonymt og skjul din ip."; +"purchase.trials.devices" = "Understøtter 10 enheder på én gang"; +"purchase.trials.devices.description" = "Beskyt dig selv på op til 10 enheder ad gangen."; +"purchase.trials.region" = "Forbind nemt til en hvilken som helst region"; +"purchase.trials.servers" = "Mere end 3300 servere i 32 lande"; +"purchase.trials.start" = "Start abonnement"; +"purchase.trials.all.plans" = "Se alle tilgængelige planer"; + +"purchase.subscribe.now" = "Tilmeld nu"; + +// WALKTHROUGH + +"walkthrough.action.next" = "NÆSTE"; +"walkthrough.action.done" = "UDFØRT"; +"walkthrough.action.skip" = "SPRING OVER"; + +"walkthrough.page.1.title" = "Understøtter 10 enheder på en gang"; +"walkthrough.page.1.description" = "Beskyt dig selv på op til 10 enheder ad gangen."; +"walkthrough.page.2.title" = "Forbind nemt til en hvilken som helst region"; +"walkthrough.page.2.description" = "Med servere rundt om i verden er du altid beskyttet."; +"walkthrough.page.3.title" = "Beskyt dig mod annoncer"; +"walkthrough.page.3.description" = "Aktivering af vores Indholdsblokering forhindrer reklamer i at blive vist i Safari."; + +"share.data.buttons.accept" = "Accepter"; +"share.data.buttons.noThanks" = "Nej tak"; +"share.data.buttons.readMore" = "Læs mere"; +"share.data.text.title" = "Hjælp os med at forbedre vores service"; +"share.data.text.description" = "For at hjælpe os med at sikre vores tjenestes forbindelsesydelse, kan du anonymt dele dine forbindelsesstatistikker med os. Disse rapporter inkluderer ikke personligt identificerbare oplysninger."; +"share.data.text.footer" = "Du kan altid kontrollere dette fra dine indstillinger"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/UI.strings new file mode 100644 index 000000000..ef42d7faf --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Luk"; +"global.ok" = "OK"; +"global.cancel" = "Annuller"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings new file mode 100644 index 000000000..6e179a032 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Log ind på din konto"; +"login.username.placeholder" = "Brugernavn (p1234567)"; +"login.password.placeholder" = "Kodeord"; +"login.submit" = "LOG IND"; +"login.restore.button" = "Modtog du ikke dine kontodetaljer?"; +"login.error.title" = "Log ind"; +"login.error.validation" = "Du skal indtaste et brugernavn og et kodeord."; +"login.error.unauthorized" = "Dit brugernavn eller kodeord er forkert."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Log på med købskvittering"; +"login.magic.link.title" = "Log ind ved hjælp af magisk e-maillink"; +"login.magic.link.response" = "Se i din e-mail for et login-link."; +"login.magic.link.send" = "Send link"; +"login.magic.link.invalid.email" = "Ugyldig e-mail. Prøv igen."; + +"purchase.title" = "Vælg en VPN-plan"; +"purchase.subtitle" = "30-dages pengene tilbage garanti"; +"purchase.email.placeholder" = "E-mailadresse"; +"purchase.continue" = "Fortsæt"; +"purchase.login.footer" = "Har du allerede en konto?"; +"purchase.login.button" = "Log ind"; +"purchase.error.title" = "Køb"; +"purchase.error.validation" = "Du skal indtaste en e-mailadresse"; +"purchase.error.connectivity.title" = "Forbindelsesfejl"; +"purchase.error.connectivity.description" = "Vi kan ikke nå Private Internet Access. Dette kan skyldes dårlig internet eller at vores service er blokeret i dit land."; +"purchase.confirm.form.email" = "Indtast din e-mailadresse"; +"purchase.confirm.plan" = "Du køber %@-planen"; +"purchase.email.why" = "Vi har brug for din e-mail for at sende dit brugernavn og din adgangskode."; +"purchase.submit" = "Indsend"; +"purchase.or" = "eller"; + +"upgrade.header" = "Velkommen tilbage!"; +"upgrade.title" = "For at bruge Private Internet Access skal du forny dit abonnement."; +"upgrade.renew.now" = "Forny nu"; + + + +"redeem.title" = "Indløs gavekort"; +"redeem.subtitle" = "Indtast din e-mailadresse, og %lu-cifrede pinkode frra dit gavekort eller prøvekort herunder."; +"redeem.email.placeholder" = "E-mailadresse"; +"redeem.submit" = "INDSEND"; +"redeem.error.title" = "Indløs"; +"redeem.error.code" = "Koden skal være %lu numeriske cifre."; +"redeem.error.allfields" = "Indtast venligst din e-mail og dit korts PIN-kode."; +"redeem.accessibility.back" = "Tilbage"; +"redeem.giftcard.placeholder" = "Gavekortets PIN-kode"; + +"plan.monthly.title" = "Månedligt"; +"plan.yearly.title" = "Årligt"; +"plan.yearly.detail_format" = "%@%@ per år"; +"plan.price_format" = "%@/mdr"; +"plan.best_value" = "Bedste værdi"; +"plan.accessibility.per_month" = "per måned"; + +"restore.title" = "Gendan ukrediteret køb"; +"restore.subtitle" = "Hvis du har købt en plan gennem denne app og ikke har modtaget dine legitimationsoplysninger, kan du anmode om at sende dem igen herfra. Du vil ikke blive opkrævet i løbet af denne proces."; +"restore.email.placeholder" = "E-mailadresse"; +"restore.submit" = "BEKRÆFT"; + +"iap.error.message.unavailable" = "Apple-servere er ikke tilgængelige i øjeblikket. Prøv venligst igen senere."; +"iap.error.title" = "Fejl"; + +"agreement.trials.title" = "Vilkår og betingelser for gratis prøveperioder"; +"agreement.trials.message" = "Betaling debiteres din Apple ID-konto ved bekræftelsen af ​​købet. Abonnementet fornyes automatisk, medmindre det annulleres mindst 24 timer inden udgangen af ​​den aktuelle periode. Din konto bliver debiteret for fornyelse inden for 24 timer inden udgangen af ​​den aktuelle periode. Du kan administrere og annullere dine abonnementer ved at gå til dine kontoindstillinger i App Store efter køb.\n\nVisse betalte abonnementer kan muligvis tilbyde en gratis prøveperiode, inden de opkræver din betalingsmetode. Hvis du beslutter at afmelde dig et betalt abonnement, før vi begynder at opkræve din betalingsmetode, skal du annullere abonnementet mindst 24 timer før den gratis prøveperiode afsluttes.\n\nGratis prøveperioder er kun tilgængelige for nye brugere og er efter vores eget skøn, og hvis du forsøger at tilmelde dig en ekstra gratis prøveperiode, bliver du straks debiteret for det almindelige abonnementsgebyr.\n\nVi forbeholder os retten til at tilbagekalde din gratis prøveperiode til enhver tid.\n\nEnhver ubrugt del af din gratis prøveperiode fortabes ved køb af et abonnement.\n\nTilmelding udgør accept af disse vilkår og betingelser."; +"agreement.message" = "Efter den gratis prøveperiode på 7 dage, fornyes dette abonnement automatisk for %@, medmindre det annulleres mindst 24 timer før prøveperioden er afsluttet. Din Apple ID-konto bliver debiteret for fornyelse inden for 24 timer inden udløbet af prøveperioden. Du kan administrere og annullere dine abonnementer ved at gå til din App Store-kontoindstillinger efter købet. Tilbudet med en 7-dages prøveperiode er begrænset til en 7-dages prøveperiode pr. bruger. Enhver ubrugt del af en gratis prøveperiode, hvis den tilbydes, fortabes, når brugeren køber et abonnement. Alle priser inkluderer gældende lokal moms.\n\nSigning up constitutes acceptance of the $1 and the $2."; +"agreement.trials.yearly.plan" = "år"; +"agreement.trials.monthly.plan" = "måned"; + +"agreement.message.tos" = "Vilkår for brug"; +"agreement.message.privacy" = "Fortrolighedspolitik"; + +"getstarted.buttons.buyaccount" = "Køb konto"; + +"gdpr.collect.data.title" = "Personlige oplysninger, vi indsamler"; +"gdpr.collect.data.description" = "E-mailadresse med henblik på kontohåndtering og beskyttelse mod misbrug."; +"gdpr.usage.data.title" = "Anvendelse af personlige oplysninger indsamlet af os"; +"gdpr.usage.data.description" = "E-mailadresse bruges kun til at sende abonnementsoplysninger, betalingsbekræftelser, kundekorrespondance og salgsfremmende tilbud fra Private Internet Access."; +"gdpr.accept.button.title" = "Accepter og fortsæt"; + +"update.account.email.error" = "Lykkedes ikke at ændre konto-e-mail"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings new file mode 100644 index 000000000..ba5d2b2b5 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Registrierung bestätigen"; +"in_progress.message" = "Wir bestätigen deinen Kauf in unserem System. Es kann einen Moment dauern, also gedulde dich bitte etwas."; +"in_progress.redeem.message" = "Wir überprüfen derzeit Ihre Karten-PIN in unserem System. Dies kann einen Moment dauern. Bitte haben Sie etwas Geduld."; + +"success.title" = "Kauf abgeschlossen"; +"success.message_format" = "Vielen Dank für deine Registrierung. Wir haben dir deinen Benutzernamen und dein Passwort an deine E-Mail-Adresse unter %@ gesendet."; +"success.redeem.title" = "Karte erfolgreich eingelöst!"; +"success.redeem.message" = "Sie werden in Kürze eine E-Mail mit Ihrem Benutzernamen und Passwort erhalten.\n\nIhre Zugangsdaten"; +"success.username.caption" = "Benutzername"; +"success.password.caption" = "Passwort"; +"success.submit" = "Erste Schritte"; + +"failure.vc_title" = "Registrierung fehlgeschlagen"; +"failure.title" = "Konto nicht erstellt"; +"failure.message" = "Zur Zeit können wir kein Konto erstellen. Bitte später erneut versuchen.\n\nBeim erneuten Öffnen der App wird wieder versucht, ein Konto zu erstellen."; +"failure.purchase.sandbox.message" = "Das ausgewählte Sandbox-Abonnement ist in der Produktion nicht verfügbar."; +"failure.redeem.invalid.title" = "Ungültige Karten-PIN"; +"failure.redeem.invalid.message" = "Anscheinend haben Sie eine ungültige PIN eingegeben. Bitte erneut versuchen."; +"failure.redeem.claimed.title" = "Karte bereits eingelöst"; +"failure.redeem.claimed.message" = "Anscheinend wurde diese Karte bereits über ein anderes Konto eingelöst. Geben Sie eine andere PIN ein."; +"failure.submit" = "ZURÜCK"; + +"unreachable.vc_title" = "Fehler"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Keine Internetverbindung gefunden. Bitte deine Internetverbindung überprüfen und erneut versuchen.\n\nDu kannst die App später erneut aufrufen, um den Vorgang abzuschließen."; +"unreachable.submit" = "WIEDERHOLEN"; + +"purchase.uncredited.alert.message" = "Sie haben Transaktionen, die noch nicht gutgeschrieben wurden. Möchten Sie Ihre Kontodaten wiederherstellen?"; +"purchase.uncredited.alert.button.cancel" = "Abbrechen"; +"purchase.uncredited.alert.button.recover" = "Konto wiederherstellen"; + +"purchase.trials.intro" = "Jetzt 7 Tage gratis testen"; +"purchase.trials.price.after" = "Dann %@"; +"purchase.trials.money.back" = "30-Tage-Geld-zurück-Garantie"; +"purchase.trials.1year.protection" = "1 Jahr Daten- und Identitätsschutz"; +"purchase.trials.anonymous" = "Anonym surfen und Ihre IP-Adresse verbergen"; +"purchase.trials.devices" = "Unterstützung für 10 Geräte"; +"purchase.trials.devices.description" = "Schützen Sie sich auf bis zu 10 Geräten gleichzeitig."; +"purchase.trials.region" = "Einfache Verbindung zu jeder Region"; +"purchase.trials.servers" = "Mehr als 3300 Server in 32 Ländern"; +"purchase.trials.start" = "Abonnement beginnen"; +"purchase.trials.all.plans" = "Alle verfügbaren Pläne anzeigen"; + +"purchase.subscribe.now" = "Jetzt abonnieren"; + +// WALKTHROUGH + +"walkthrough.action.next" = "WEITER"; +"walkthrough.action.done" = "FERTIG"; +"walkthrough.action.skip" = "ÜBERSPRINGEN"; + +"walkthrough.page.1.title" = "Unterstützung für 10 Geräte"; +"walkthrough.page.1.description" = "Schützen Sie sich auf bis zu 10 Geräten gleichzeitig."; +"walkthrough.page.2.title" = "Bequem mit jeder beliebigen Region verbinden"; +"walkthrough.page.2.description" = "Mit Servern auf der ganzen Welt bist du immer geschützt."; +"walkthrough.page.3.title" = "Schütze dich vor Werbung"; +"walkthrough.page.3.description" = "Mit der Aktivierung unseres Inhalts-Blockers sehen Sie keine Anzeigen in Safari mehr."; + +"share.data.buttons.accept" = "Akzeptieren"; +"share.data.buttons.noThanks" = "Nein danke"; +"share.data.buttons.readMore" = "Mehr erfahren"; +"share.data.text.title" = "Bitte helfen Sie uns, unseren Service zu verbessern"; +"share.data.text.description" = "Um uns zu helfen, die Verbindungsleistung unseres Dienstes sicherzustellen, können Sie Ihre Verbindungsstatistiken anonym mit uns teilen. Diese Berichte enthalten keine persönlich identifizierbaren Informationen."; +"share.data.text.footer" = "Sie können dies jederzeit über Ihre Einstellungen steuern"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/UI.strings new file mode 100644 index 000000000..4268a80ca --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Schließen"; +"global.ok" = "OK"; +"global.cancel" = "Abbrechen"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings new file mode 100644 index 000000000..ed13eb4ab --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "An deinem Konto anmelden"; +"login.username.placeholder" = "Benutzername (p1234567)"; +"login.password.placeholder" = "Passwort"; +"login.submit" = "ANMELDEN"; +"login.restore.button" = "Keine Kontodaten erhalten?"; +"login.error.title" = "Anmelden"; +"login.error.validation" = "Du musst einen Benutzernamen und ein Passwort angeben."; +"login.error.unauthorized" = "Dein Benutzername oder Passwort ist falsch."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Anmeldung mit Kaufbeleg"; +"login.magic.link.title" = "Anmeldung mit magischem E-Mail-Link"; +"login.magic.link.response" = "Bitte überprüfen Sie Ihre E-Mail auf einen Login-Link."; +"login.magic.link.send" = "Link senden"; +"login.magic.link.invalid.email" = "Ungültige E-Mail-Adresse. Bitte erneut versuchen."; + +"purchase.title" = "VPN-Tarif auswählen"; +"purchase.subtitle" = "30-Tage-Geld-zurück-Garantie"; +"purchase.email.placeholder" = "E-Mail-Adresse"; +"purchase.continue" = "Weiter"; +"purchase.login.footer" = "Bereits ein Konto?"; +"purchase.login.button" = "Anmelden"; +"purchase.error.title" = "Kaufen"; +"purchase.error.validation" = "Sie müssen eine E-Mail-Adresse angeben."; +"purchase.error.connectivity.title" = "Verbindungsfehler"; +"purchase.error.connectivity.description" = "Wir können Private Internet Access nicht erreichen. Dies kann auf eine schlechte Internetverbindung zurückzuführen sein oder unser Service ist in deinem Land blockiert."; +"purchase.confirm.form.email" = "E-Mail-Adresse eingeben"; +"purchase.confirm.plan" = "Sie erwerben den %@-Tarif."; +"purchase.email.why" = "Wir benötigen Ihre E-Mail, um Ihren Benutzernamen und Ihr Passwort zu senden."; +"purchase.submit" = "Senden"; +"purchase.or" = "oder"; + +"upgrade.header" = "Willkommen zurück!"; +"upgrade.title" = "Sie müssen Ihr Abonnement erneuern, um Private Internet Access nutzen zu können."; +"upgrade.renew.now" = "Jetzt erneuern"; + + + +"redeem.title" = "Geschenkkarte einlösen"; +"redeem.subtitle" = "Geben Sie unten Ihre E-Mail-Adresse und die %lu-stellige PIN von Ihrer Geschenk- oder Testkarte ein."; +"redeem.email.placeholder" = "E-Mail-Adresse"; +"redeem.submit" = "SENDEN"; +"redeem.error.title" = "Einlösen"; +"redeem.error.code" = "Der Code muss aus %lu Ziffern bestehen."; +"redeem.error.allfields" = "Bitte geben Sie Ihre E-Mail-Adresse und Karten-PIN ein."; +"redeem.accessibility.back" = "Zurück"; +"redeem.giftcard.placeholder" = "PIN der Geschenkkarte"; + +"plan.monthly.title" = "Monatlich"; +"plan.yearly.title" = "Jährlich"; +"plan.yearly.detail_format" = "%@%@ pro Jahr"; +"plan.price_format" = "%@/Monat"; +"plan.best_value" = "Bestpreis"; +"plan.accessibility.per_month" = "pro Monat"; + +"restore.title" = "Nicht gutgeschriebenen Kauf wiederherstellen"; +"restore.subtitle" = "Wenn Sie einen Tarif über diese App erworben haben und Ihre Zugangsdaten nicht erhalten haben, können Sie sie hier erneut anfordern. Sie müssen dann nicht erneut bezahlen."; +"restore.email.placeholder" = "E-Mail-Adresse"; +"restore.submit" = "BESTÄTIGEN"; + +"iap.error.message.unavailable" = "Die Apple-Server sind momentan nicht verfügbar. Bitte später erneut versuchen."; +"iap.error.title" = "Fehler"; + +"agreement.trials.title" = "Nutzungsbedingungen für kostenlose Testversionen"; +"agreement.trials.message" = "Die Zahlung wird Ihrem Apple ID-Konto bei der Kaufbestätigung belastet. Das Abonnement verlängert sich automatisch, wenn es nicht mindestens 24 Stunden vor Ablauf der aktuellen Periode gekündigt wird. Die Verlängerung wird Ihrem Konto innerhalb von 24 Stunden vor Ablauf der aktuellen Periode in Rechnung gestellt. Sie können Ihre Abonnements verwalten und kündigen, indem Sie nach dem Kauf zu Ihren Kontoeinstellungen im App Store aufrufen.\n\nBestimmte kostenpflichtige Abonnements können eine kostenlose Testversion anbieten, bevor Sie Ihre Zahlungsmethode berechnen. Wenn Sie sich entscheiden, sich von einem kostenpflichtigen Abonnement abzumelden, bevor wir mit der Berechnung Ihrer Zahlungsmethode beginnen, kündigen Sie das Abonnement mindestens 24 Stunden vor Ablauf der kostenlosen Probezeit.\n\nKostenlose Testversionen sind nur für neue Benutzer verfügbar und liegen in unserem alleinigen Ermessen, und wenn Sie versuchen, sich für eine zusätzliche kostenlose Testversion anzumelden, wird Ihnen sofort die Standard-Abonnementgebühr in Rechnung gestellt.\n\nWir behalten uns das Recht vor, Ihre kostenlose Testversion jederzeit zu widerrufen.\n\nJeder ungenutzte Teil Ihrer kostenlosen Probezeit verfällt mit dem Kauf eines Abonnements.\n\nMit der Registrierung akzeptieren Sie diese Nutzungsbedingungen."; +"agreement.message" = "Nach der 7-tägigen kostenlosen Testperiode verlängert sich dieses Abonnement automatisch für %@, sofern es nicht mindestens 24 Stunden vor Ablauf der Testperiode gekündigt wird. Ihr Apple-ID-Konto wird für die Verlängerung innerhalb von 24 Stunden vor Ablauf des Testzeitraums belastet. Sie können Ihre Abonnements nach dem Kauf in den Einstellungen Ihres App Store-Kontos verwalten und kündigen. Jeder Benutzer kann die 7-tägige kostenlose Testperiode nur einmal in Anspruch nehmen. Jeder nicht genutzte Teil einer kostenlosen Testperiode, falls angeboten, verfällt beim Kauf eines Abonnements durch den Benutzer. Alle Preise enthalten die örtlich geltenden Verkaufssteuern.\n\nMit der Anmeldung akzeptieren Sie die $1 und $2."; +"agreement.trials.yearly.plan" = "Jahr"; +"agreement.trials.monthly.plan" = "Monat"; + +"agreement.message.tos" = "Nutzungsbedingungen"; +"agreement.message.privacy" = "Datenschutzrichtlinien"; + +"getstarted.buttons.buyaccount" = "Konto kaufen"; + +"gdpr.collect.data.title" = "Art der personenbezogenen Daten, die wir erfassen"; +"gdpr.collect.data.description" = "E-Mail-Adresse zum Zwecke der Kontoverwaltung und zum Schutz vor Missbrauch."; +"gdpr.usage.data.title" = "Verwendungszwecke für personenbezogene Daten, die von uns erfasst wurden"; +"gdpr.usage.data.description" = "Die E-Mail-Adresse wird lediglich zum Senden von Abonnementinformationen, Zahlungsbestätigungen, Kundenkorrespondenz und Sonderangeboten zu Private Internet Access verwendet."; +"gdpr.accept.button.title" = "Zustimmen und fortfahren"; + +"update.account.email.error" = "Konto-E-Mail nicht geändert"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings new file mode 100644 index 000000000..dacff3d57 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirm sign-up"; +"in_progress.message" = "We're confirming your purchase with our system. It could take a moment so hang in there."; +"in_progress.redeem.message" = "We're confirming your card PIN with our system. It could take a moment so hang in there."; + +"success.title" = "Purchase complete"; +"success.message_format" = "Thank you for signing up with us. We have sent your account username and password at your email address at %@"; +"success.redeem.title" = "Card redeemed successfully"; +"success.redeem.message" = "You will receive an email shortly with your username and password.\n\nYour login details"; +"success.username.caption" = "Username"; +"success.password.caption" = "Password"; +"success.submit" = "GET STARTED"; + +"failure.vc_title" = "Sign-up failed"; +"failure.title" = "Account creation failed"; +"failure.message" = "We're unable to create an account at this time. Please try again later. Reopening the app will re-attempt to create an account."; +"failure.purchase.sandbox.message" = "The selected sandbox subscription is not available in production."; +"failure.redeem.invalid.title" = "Invalid card PIN"; +"failure.redeem.invalid.message" = "Looks like you entered an invalid card PIN. Please try again."; +"failure.redeem.claimed.title" = "Card claimed already"; +"failure.redeem.claimed.message" = "Looks like this card has already been claimed by another account. You can try entering a different PIN."; +"failure.submit" = "GO BACK"; + +"unreachable.vc_title" = "Error"; +"unreachable.title" = "Whoops!"; +"unreachable.message" = "No internet connection found. Please confirm that you have an internet connection and hit retry below.\n\nYou can come back to the app later to finish the process."; +"unreachable.submit" = "TRY AGAIN"; + +"purchase.uncredited.alert.message" = "You have uncredited transactions. Do you want to recover your account details?"; +"purchase.uncredited.alert.button.cancel" = "Cancel"; +"purchase.uncredited.alert.button.recover" = "Recover account"; + +"purchase.trials.intro" = "Start your 7-day free trial"; +"purchase.trials.price.after" = "Then %@"; +"purchase.trials.money.back" = "30 day money back guarantee"; +"purchase.trials.1year.protection" = "1 year of privacy and identity protection"; +"purchase.trials.anonymous" = "Browse anonymously and hide your ip."; +"purchase.trials.devices" = "Support 10 devices at once"; +"purchase.trials.devices.description" = "Protect yourself on up to 10 devices at a time."; +"purchase.trials.region" = "Connect to any region easily"; +"purchase.trials.servers" = "More than 3300 servers in 32 countries"; +"purchase.trials.start" = "Start subscription"; +"purchase.trials.all.plans" = "See all available plans"; + +"purchase.subscribe.now" = "Subscribe now"; + +// WALKTHROUGH + +"walkthrough.action.next" = "NEXT"; +"walkthrough.action.done" = "DONE"; +"walkthrough.action.skip" = "SKIP"; + +"walkthrough.page.1.title" = "Support 10 devices at once"; +"walkthrough.page.1.description" = "Protect yourself on up to 10 devices at a time."; +"walkthrough.page.2.title" = "Connect to any region easily"; +"walkthrough.page.2.description" = "With servers around the globe, you are always under protection."; +"walkthrough.page.3.title" = "Protect yourself from ads"; +"walkthrough.page.3.description" = "Enabling our Content Blocker prevents ads from showing in Safari."; + +"share.data.buttons.accept" = "Accept"; +"share.data.buttons.noThanks" = "No, thanks"; +"share.data.buttons.readMore" = "Read more"; +"share.data.text.title" = "Please help us improve our service"; +"share.data.text.description" = "To help us ensure our service's connection performance, you can anonymously share your connection stats with us. These reports do not include any personally identifiable information."; +"share.data.text.footer" = "You can always control this from your settings"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/UI.strings new file mode 100644 index 000000000..98ec3d5e2 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Close"; +"global.ok" = "OK"; +"global.cancel" = "Cancel"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings new file mode 100644 index 000000000..91c5c4c53 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Sign in to your account"; +"login.username.placeholder" = "Username (p1234567)"; +"login.password.placeholder" = "Password"; +"login.submit" = "LOGIN"; +"login.restore.button" = "Didn't receive account details?"; +"login.error.title" = "Log in"; +"login.error.validation" = "You must enter a username and password."; +"login.error.unauthorized" = "Your username or password is incorrect."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Login using purchase receipt"; +"login.magic.link.title" = "Login using magic email link"; +"login.magic.link.response" = "Please check your e-mail for a login link."; +"login.magic.link.send" = "Send Link"; +"login.magic.link.invalid.email" = "Invalid email. Please try again."; + +"purchase.title" = "Select a VPN plan"; +"purchase.subtitle" = "30-day money back guarantee"; +"purchase.email.placeholder" = "Email address"; +"purchase.continue" = "Continue"; +"purchase.login.footer" = "Already have an account?"; +"purchase.login.button" = "Sign in"; +"purchase.error.title" = "Purchase"; +"purchase.error.validation" = "You must enter an email address."; +"purchase.error.connectivity.title" = "Connection Failure"; +"purchase.error.connectivity.description" = "We are unable to reach Private Internet Access. This may due to poor internet or our service is blocked in your country."; +"purchase.confirm.form.email" = "Enter your email address"; +"purchase.confirm.plan" = "You are purchasing the %@ plan"; +"purchase.email.why" = "We need your email to send your username and password."; +"purchase.submit" = "Submit"; +"purchase.or" = "or"; + +"upgrade.header" = "Welcome Back!"; +"upgrade.title" = "In order to use Private Internet Access, you’ll need to renew your subscription."; +"upgrade.renew.now" = "Renew now"; + + + +"redeem.title" = "Redeem gift card"; +"redeem.subtitle" = "Type in your email address and the %lu digit PIN from your gift card or trial card below."; +"redeem.email.placeholder" = "Email address"; +"redeem.submit" = "SUBMIT"; +"redeem.error.title" = "Redeem"; +"redeem.error.code" = "Code must be %lu numeric digits."; +"redeem.error.allfields"="Please type in your email and card PIN."; +"redeem.accessibility.back" = "Back"; +"redeem.giftcard.placeholder" = "Gift card PIN"; + +"plan.monthly.title" = "Monthly"; +"plan.yearly.title" = "Yearly"; +"plan.yearly.detail_format" = "%@%@ per year"; +"plan.price_format" = "%@/mo"; +"plan.best_value" = "Best value"; +"plan.accessibility.per_month" = "per month"; + +"restore.title" = "Restore uncredited purchase"; +"restore.subtitle" = "If you purchased a plan through this app and didn't receive your credentials, you can send them again from here. You will not be charged during this process."; +"restore.email.placeholder" = "Email address"; +"restore.submit" = "CONFIRM"; + +"iap.error.message.unavailable" = "Apple servers currently unavailable. Please try again later."; +"iap.error.title" = "Error"; + +"agreement.trials.title" = "Free trials terms and conditions"; +"agreement.trials.message" = "Payment will be charged to your Apple ID account at the confirmation of purchase. Subscription automatically renews unless it is canceled at least 24 hours before the end of the current period. Your account will be charged for renewal within 24 hours prior to the end of the current period. You can manage and cancel your subscriptions by going to your account settings on the App Store after purchase.\n\nCertain Paid Subscriptions may offer a free trial prior to charging your payment method. If you decide to unsubscribe from a Paid Subscription before we start charging your payment method, cancel the subscription at least 24 hours before the free trial ends.\n\nFree trials are only available to new users, and are at our sole discretion, and if you attempt to sign up for an additional free trial, you will be immediately charged with the standard Subscription Fee.\n\nWe reserve the right to revoke your free trial at any time.\n\nAny unused portion of your free trial period will be forfeited upon purchase of a subscription.\n\nSigning up constitutes acceptance of this terms and conditions."; +"agreement.message" = "After the 7 days free trial this subscription automatically renews for %@ unless it is canceled at least 24 hours before the end of the trial period. Your Apple ID account will be charged for renewal within 24 hours before the end of the trial period. You can manage and cancel your subscriptions by going to your App Store account settings after purchase. 7-days trial offer is limited to one 7-days trial offer per user. Any unused portion of a free trial period, if offered, will be forfeited when the user purchases a subscription. All prices include applicable local sales taxes.\n\nSigning up constitutes acceptance of the $1 and the $2."; +"agreement.trials.yearly.plan" = "year"; +"agreement.trials.monthly.plan" = "month"; + +"agreement.message.tos" = "Terms of Service"; +"agreement.message.privacy" = "Privacy Policy"; + +"getstarted.buttons.buyaccount" = "Buy account"; + +"gdpr.collect.data.title" = "Personal information we collect"; +"gdpr.collect.data.description" = "E-mail Address for the purposes of account management and protection from abuse."; +"gdpr.usage.data.title" = "Uses of personal information collected by us"; +"gdpr.usage.data.description" = "E-mail address is used to send subscription information, payment confirmations, customer correspondence, and Private Internet Access promotional offers only."; +"gdpr.accept.button.title" = "Agree and continue"; + +"update.account.email.error" = "Failed to modify account email"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings new file mode 100644 index 000000000..3ebdb9fd3 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirmar registro"; +"in_progress.message" = "Estamos confirmando la compra en el sistema. Podrías tardar unos instantes, así que espera."; +"in_progress.redeem.message" = "Estamos confirmando el PIN de tu tarjeta en nuestro sistema. Puede tardar un momento, así que espera un poco."; + +"success.title" = "Compra completa"; +"success.message_format" = "Gracias por registrarte con nosotros. Te enviamos el nombre de usuario y contraseña de tu cuenta a tu dirección de email en %@"; +"success.redeem.title" = "Tarjeta canjeada correctamente"; +"success.redeem.message" = "Recibirás un mensaje de correo electrónico dentro de poco con tu nombre de usuario y contraseña.\n\nTu información de inicio de sesión"; +"success.username.caption" = "Nombre de usuario"; +"success.password.caption" = "Contraseña "; +"success.submit" = "Empieza"; + +"failure.vc_title" = "Falló el registro"; +"failure.title" = "Falló la creación de la cuenta"; +"failure.message" = "No pudimos crear una cuenta en este momento. Por favor, inténtalo de nuevo más tarde. \nSi vuelves a abrir la aplicación intentaremos crear una cuenta otra vez."; +"failure.purchase.sandbox.message" = "La suscripción del entorno aislado seleccionado no está disponible en la producción."; +"failure.redeem.invalid.title" = "El PIN de la tarjeta no es válido"; +"failure.redeem.invalid.message" = "Parece que ingresaste un PIN de tarjeta inválido. Por favor, inténtalo de nuevo."; +"failure.redeem.claimed.title" = "La tarjeta ya fue reclamada"; +"failure.redeem.claimed.message" = "Parece que esta tarjeta ha sido reclamada por otra cuenta. Puedes intentar ingresar un PIN diferente."; +"failure.submit" = "ATRÁS"; + +"unreachable.vc_title" = "Error"; +"unreachable.title" = "¡Ups!"; +"unreachable.message" = "No se encontró conexión a Internet. Por favor, confirma que tienes una conexión a Internet y toca en intentar de nuevo más abajo.\n\nPuedes regresar después a la aplicación para terminar el proceso."; +"unreachable.submit" = "VOLVER A INTENTAR"; + +"purchase.uncredited.alert.message" = "Tienes transacciones sin acreditar. ¿Seguro que quieres recuperar los detalles de tu cuenta?"; +"purchase.uncredited.alert.button.cancel" = "Cancelar"; +"purchase.uncredited.alert.button.recover" = "Recuperar cuenta"; + +"purchase.trials.intro" = "Inicia tu prueba gratuita de 7 días"; +"purchase.trials.price.after" = "Después, %@"; +"purchase.trials.money.back" = "Garantía de devolución de 30 días"; +"purchase.trials.1year.protection" = "1 año de privacidad y protección de la identidad."; +"purchase.trials.anonymous" = "Navega de forma anónima y oculta tu IP."; +"purchase.trials.devices" = "Admite 10 dispositivos a la vez."; +"purchase.trials.devices.description" = "Protégete en hasta 10 dispositivos a la vez."; +"purchase.trials.region" = "Conéctate a cualquier región con facilidad."; +"purchase.trials.servers" = "Más de 3300 servidores en 32 países."; +"purchase.trials.start" = "Iniciar suscripción"; +"purchase.trials.all.plans" = "Ver todos los planes disponibles."; + +"purchase.subscribe.now" = "Suscríbete ahora"; + +// WALKTHROUGH + +"walkthrough.action.next" = "SIGUIENTE"; +"walkthrough.action.done" = "TERMINADO"; +"walkthrough.action.skip" = "OMITIR"; + +"walkthrough.page.1.title" = "Admite 10 dispositivos a la vez"; +"walkthrough.page.1.description" = "Protégete en hasta 10 dispositivos a la vez."; +"walkthrough.page.2.title" = "Conéctate a cualquier región con facilidad"; +"walkthrough.page.2.description" = "Con servidores en todo el mundo, siempre estarás protegido."; +"walkthrough.page.3.title" = "Protégete de la publicidad"; +"walkthrough.page.3.description" = "Habilita nuestro Bloqueador de contenido para impedir que aparezca publicidad en Safari."; + +"share.data.buttons.accept" = "Aceptar"; +"share.data.buttons.noThanks" = "No, gracias"; +"share.data.buttons.readMore" = "Más información"; +"share.data.text.title" = "Ayúdanos a mejorar nuestro servicio."; +"share.data.text.description" = "Para ayudarnos a garantizar el rendimiento de la conexión de nuestro servicio, puedes compartir con nosotros tus estadísticas de conexión de forma anónima. Estos informes no contienen ninguna información personal identificable."; +"share.data.text.footer" = "Siempre puedes controlarlo desde tus ajustes."; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings new file mode 100644 index 000000000..e645f72b5 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versión %@ (%@)"; +"global.close" = "Cerrar"; +"global.ok" = "Aceptar"; +"global.cancel" = "Cancelar"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings new file mode 100644 index 000000000..3c47f73e3 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Inicia sesión en tu cuenta"; +"login.username.placeholder" = "Nombre de usuario (p1234567)"; +"login.password.placeholder" = "Contraseña "; +"login.submit" = "INICIAR SESIÓN"; +"login.restore.button" = "¿No has recibido los detalles de la cuenta?"; +"login.error.title" = "Iniciar sesión"; +"login.error.validation" = "Debe ingresar un nombre de usuario y una contraseña."; +"login.error.unauthorized" = "Tu nombre de usuario o contraseña son incorrectos."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Inicia sesión con el recibo de compra"; +"login.magic.link.title" = "Inicia sesión con el vínculo mágico del correo electrónico."; +"login.magic.link.response" = "Busca en tu correo electrónico un enlace de inicio de sesión."; +"login.magic.link.send" = "Enviar enlace"; +"login.magic.link.invalid.email" = "Correo electrónico no válido. Vuelve a intentarlo."; + +"purchase.title" = "Selecciona un plan VPN"; +"purchase.subtitle" = "Garantía de devolución de 30 días"; +"purchase.email.placeholder" = "Dirección de correo electrónico"; +"purchase.continue" = "Continuar"; +"purchase.login.footer" = "¿Ya tienes una cuenta?"; +"purchase.login.button" = "Inicia sesión"; +"purchase.error.title" = "Comprar"; +"purchase.error.validation" = "Debes ingresar una dirección de email."; +"purchase.error.connectivity.title" = "Falla en la conexión"; +"purchase.error.connectivity.description" = "No pudimos localizar a Private Internet Access. Esto puede ser debido a una mala conexión con Internet o a que nuestro servicio está bloqueado en su país."; +"purchase.confirm.form.email" = "Introduce tu dirección de correo electrónico"; +"purchase.confirm.plan" = "Estás comprando el plan %@."; +"purchase.email.why" = "Necesitamos tu dirección de correo electrónico para enviar tu nombre de usuario y tu contraseña."; +"purchase.submit" = "Enviar"; +"purchase.or" = "o"; + +"upgrade.header" = "¡Hola otra vez!"; +"upgrade.title" = "Para usar Private Internet Access debes renovar tu suscripción."; +"upgrade.renew.now" = "Renovar ahora"; + + + +"redeem.title" = "Canjear tarjeta de regalo"; +"redeem.subtitle" = "Escribe abajo tu dirección de correo electrónico y el PIN de %lu dígitos de tu tarjeta de regalo o tarjeta de prueba."; +"redeem.email.placeholder" = "Dirección de correo electrónico"; +"redeem.submit" = "ENVIAR"; +"redeem.error.title" = "Canjear"; +"redeem.error.code" = "El código debe tener %lu dígitos numéricos."; +"redeem.error.allfields" = "Escribe tu dirección de correo electrónico y el PIN de tu tarjeta."; +"redeem.accessibility.back" = "Volver"; +"redeem.giftcard.placeholder" = "PIN de tarjeta regalo"; + +"plan.monthly.title" = "Mensual"; +"plan.yearly.title" = "Anual"; +"plan.yearly.detail_format" = "%@%@ al año"; +"plan.price_format" = "%@/m"; +"plan.best_value" = "Mejor oferta"; +"plan.accessibility.per_month" = "por mes"; + +"restore.title" = "Restablecer compra no acreditada"; +"restore.subtitle" = "Si compraste un plan a través de esta aplicación y no recibes tus credenciales, puedes reiniciar la renovación desde aquí. No se realizarán cargos durante este proceso. \n"; +"restore.email.placeholder" = "Correo electrónico"; +"restore.submit" = "CONFIRMAR"; + +"iap.error.message.unavailable" = "Actualmente, los servidores de Apple no están disponibles. Por favor, inténtalo de nuevo más tarde."; +"iap.error.title" = "Error"; + +"agreement.trials.title" = "Términos y condiciones de la prueba gratuita."; +"agreement.trials.message" = "Se realizará un cobro en tu cuenta de Apple ID en el momento de confirmar la compra. Las suscripciones se renuevan automáticamente a menos que se cancelen como mínimo 24 horas antes de la finalización del periodo actual. Se cobrará la cantidad de la renovación en un plazo de 24 horas antes de la finalización del período actual. Tu mismo podrás gestionar y cancelar las suscripciones en los ajustes de App Store después de la compra. \n\nAlgunas suscripciones de pago pueden ofrecer una prueba gratuita antes de realizar cobros según tu método de pago. Si decides darte de baja de una suscripción de pago antes de que comencemos a cobrar tu método de pago, cancela la suscripción al menos 24 horas antes de que finalice la prueba gratuita.\n\nLas pruebas gratuitas solo están disponibles para nuevos usuarios y quedan a nuestra entera discreción. Si intentas registrarte para obtener una prueba gratuita adicional, se te cobrará de inmediato la tarifa de suscripción estándar.\n\nNos reservamos el derecho de revocar tu prueba gratuita en cualquier momento.\n\nLas secciones sin usar del periodo de prueba gratuito se perderán si el usuario compra una suscripción.\n\nSi te registras, aceptas estos términos y condiciones."; +"agreement.message" = "Después de los 7 días de prueba gratuita, esta suscripción se renueva automáticamente por %@ a menos que se cancele al menos 24 horas antes del final del período de prueba. Se cobrará la renovación en tu cuenta de ID de Apple en un plazo de 24 horas antes de que finalice el periodo de prueba. Puedes gestionar y cancelar tus suscripciones accediendo a los ajustes de tu cuenta de App Store después de la compra. La oferta de prueba de 7 días se limita a una oferta de prueba de 7 días por usuario. Cualquier parte no utilizada de un período de prueba gratuito, si se ofrece, se perderá cuando el usuario compre una suscripción. Todos los precios incluyen los impuestos de venta locales aplicables.\n\nSi te registras, aceptas los $1 y la $2."; +"agreement.trials.yearly.plan" = "año"; +"agreement.trials.monthly.plan" = "mes"; + +"agreement.message.tos" = "Términos de servicio"; +"agreement.message.privacy" = "Política de privacidad"; + +"getstarted.buttons.buyaccount" = "Comprar cuenta"; + +"gdpr.collect.data.title" = "Información personal que recopilamos"; +"gdpr.collect.data.description" = "Dirección de correo electrónico con fines de gestión de cuenta y protección frente a abusos."; +"gdpr.usage.data.title" = "Usos de la información personal que recopilamos"; +"gdpr.usage.data.description" = "La dirección de correo electrónico solo se usa para enviar información de suscripción, confirmaciones de pago, correspondencia al cliente y ofertas promocionales de Private Internet Access."; +"gdpr.accept.button.title" = "Aceptar y continuar"; + +"update.account.email.error" = "Error al modificar el correo electrónico de la cuenta"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings new file mode 100644 index 000000000..a99c30197 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirmation d'inscription"; +"in_progress.message" = "Notre système est en train de confirmer votre achat. Cela pourrait prendre un moment, nous vous prions donc de patienter."; +"in_progress.redeem.message" = "Notre système est en train de confirmer le code PIN de votre carte. Cela pourrait prendre un moment, nous vous prions donc de patienter."; + +"success.title" = "Achat terminé"; +"success.message_format" = "Merci pour votre inscription. L'identifiant et le mot de passe de votre compte ont été envoyés à votre adresse e-mail %@"; +"success.redeem.title" = "Carte échangée avec succès"; +"success.redeem.message" = "Vous allez bientôt recevoir un e-mail contenant votre nom d'utilisateur et votre mot de passe.\n\nDétails de vos identifiants"; +"success.username.caption" = "Nom d'utilisateur"; +"success.password.caption" = "Mot de passe"; +"success.submit" = "Commencer"; + +"failure.vc_title" = "Échec de la connexion"; +"failure.title" = "La création du compte a échoué"; +"failure.message" = "Nous ne parvenons pas à créer un compte pour l'instant. Veuillez réessayer plus tard. \n\nRouvrir l'application engendrera une nouvelle tentative de création de compte."; +"failure.purchase.sandbox.message" = "L'abonnement sandbox sélectionné n'est pas disponible en production."; +"failure.redeem.invalid.title" = "Code PIN de la carte invalide"; +"failure.redeem.invalid.message" = "Il semblerait que le code PIN de la carte saisie soit invalide. Veuillez réessayer."; +"failure.redeem.claimed.title" = "Carte déjà utilisée"; +"failure.redeem.claimed.message" = "Il semblerait que cette carte soit déjà utilisée sur un autre compte. Vous pouvez essayer de saisir un code PIN différent."; +"failure.submit" = "REVENIR"; + +"unreachable.vc_title" = "Erreur"; +"unreachable.title" = "Oups !"; +"unreachable.message" = "Aucune connexion Internet trouvée. Veuillez confirmer que vous disposez d'une connexion Internet et cliquez de nouveau sur « Réessayer » ci-dessous.\n\nVous pourrez revenir dans l'application plus tard pour terminer le processus."; +"unreachable.submit" = "RÉESSAYER"; + +"purchase.uncredited.alert.message" = "Vous avez des transaction non créditées. Voulez-vous restaurer les détails de votre compte ?"; +"purchase.uncredited.alert.button.cancel" = "Annuler"; +"purchase.uncredited.alert.button.recover" = "Restaurer le compte"; + +"purchase.trials.intro" = "Démarrez votre essai gratuit de 7 jours"; +"purchase.trials.price.after" = "Ensuite %@"; +"purchase.trials.money.back" = "Garantie satisfait ou remboursé sur 30 jours"; +"purchase.trials.1year.protection" = "1 an de confidentialité et de protection de l'identité"; +"purchase.trials.anonymous" = "Surfez anonymement et masquez votre IP."; +"purchase.trials.devices" = "Prise en charge de 10 appareils en même temps"; +"purchase.trials.devices.description" = "Protégez-vous sur jusqu'à 10 appareils en même temps."; +"purchase.trials.region" = "Connectez-vous facilement à n'importe quelle région"; +"purchase.trials.servers" = "Plus de 3300 serveurs dans 32 pays"; +"purchase.trials.start" = "Commencer l'abonnement"; +"purchase.trials.all.plans" = "Voir tous les forfaits disponibles"; + +"purchase.subscribe.now" = "S'abonner maintenant"; + +// WALKTHROUGH + +"walkthrough.action.next" = "SUIVANT"; +"walkthrough.action.done" = "TERMINÉ"; +"walkthrough.action.skip" = "PASSER"; + +"walkthrough.page.1.title" = "Prend en charge 10 appareils en même temps"; +"walkthrough.page.1.description" = "Protégez-vous sur jusqu'à 10 appareils à la fois."; +"walkthrough.page.2.title" = "Connectez-vous facilement à n'importe quelle région"; +"walkthrough.page.2.description" = "Avec des serveurs partout dans le monde, vous êtes toujours sous protection."; +"walkthrough.page.3.title" = "Protégez-vous contre les publicités"; +"walkthrough.page.3.description" = "Activer notre bloqueur de contenu empêche les publicités de s'afficher dans Safari."; + +"share.data.buttons.accept" = "Accepter"; +"share.data.buttons.noThanks" = "Non, merci"; +"share.data.buttons.readMore" = "Lire plus"; +"share.data.text.title" = "Merci de nous aider à améliorer notre service"; +"share.data.text.description" = "Pour nous aider à garantir les performances de connexion de notre service, vous pouvez partager vos statistiques de connexion de manière anonyme avec nous. Ces rapports ne contiennent aucune information personnellement identifiable."; +"share.data.text.footer" = "Vous pouvez toujours contrôler cela à partir de vos paramètres."; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings new file mode 100644 index 000000000..fffdf519f --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Fermer"; +"global.ok" = "OK"; +"global.cancel" = "Annuler"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings new file mode 100644 index 000000000..623c17c3a --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Connectez-vous à votre compte"; +"login.username.placeholder" = "Nom d'utilisateur (p1234567)"; +"login.password.placeholder" = "Mot de passe"; +"login.submit" = "CONNEXION"; +"login.restore.button" = "Vous n'avez pas reçu les détails de votre compte ?"; +"login.error.title" = "Connexion"; +"login.error.validation" = "Vous devez saisir un nom d'utilisateur et un mot de passe."; +"login.error.unauthorized" = "Votre nom d'utilisateur ou mot de passe est incorrect."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Connectez-vous à l'aide du reçu d'achat"; +"login.magic.link.title" = "Connectez-vous à l'aide du lien e-mail magique"; +"login.magic.link.response" = "Veuillez vérifier vos e-mails pour trouver un lien de connexion."; +"login.magic.link.send" = "Envoyer un lien"; +"login.magic.link.invalid.email" = "E-mail invalide. Veuillez réessayer."; + +"purchase.title" = "Sélectionnez un forfait VPN"; +"purchase.subtitle" = "Garantie satisfait ou remboursé sur 30 jours"; +"purchase.email.placeholder" = "Adresse e-mail"; +"purchase.continue" = "Continuer"; +"purchase.login.footer" = "Vous avez déjà un compte ?"; +"purchase.login.button" = "Connectez-vous"; +"purchase.error.title" = "Acheter"; +"purchase.error.validation" = "Vous devez entrer une adresse e-mail."; +"purchase.error.connectivity.title" = "Échec de la connexion"; +"purchase.error.connectivity.description" = "Nous n'arrivons pas à joindre Private Internet Access. Cela peut être dû à une connexion Internet de faible qualité ou parce que notre service est bloqué dans votre pays."; +"purchase.confirm.form.email" = "Saisissez votre adresse e-mail"; +"purchase.confirm.plan" = "Vous achetez le forfait %@"; +"purchase.email.why" = "Nous avons besoin de votre e-mail pour envoyer votre nom d'utilisateur et votre mot de passe."; +"purchase.submit" = "Envoyer"; +"purchase.or" = "ou"; + +"upgrade.header" = "Bienvenue !"; +"upgrade.title" = "Afin d'utiliser Private Internet Access, vous devrez renouveler votre abonnement."; +"upgrade.renew.now" = "Renouveler maintenant"; + + + +"redeem.title" = "Échanger carte cadeau"; +"redeem.subtitle" = "Veuillez saisir ci-dessous votre adresse e-mail et le code PIN à %lu chiffres de votre carte cadeau ou carte d'essai."; +"redeem.email.placeholder" = "Adresse e-mail"; +"redeem.submit" = "ENVOYER"; +"redeem.error.title" = "Échanger"; +"redeem.error.code" = "Le code doit contenir %lu chiffres numériques."; +"redeem.error.allfields" = "Saisissez votre e-mail et le code PIN de votre carte."; +"redeem.accessibility.back" = "Retour"; +"redeem.giftcard.placeholder" = "Code PIN de la carte"; + +"plan.monthly.title" = "Mensuellement"; +"plan.yearly.title" = "Annuellement"; +"plan.yearly.detail_format" = "%@%@ par an"; +"plan.price_format" = "%@/mois"; +"plan.best_value" = "Économique"; +"plan.accessibility.per_month" = "par mois"; + +"restore.title" = "Restaurer l'achat non crédité"; +"restore.subtitle" = "Si vous avez acheté un forfait via cette application et n'avez pas reçu vos identifiants, il est possible de les renvoyer à partir d'ici. Cette action ne vous sera pas facturée."; +"restore.email.placeholder" = "Adresse e-mail"; +"restore.submit" = "CONFIRMER"; + +"iap.error.message.unavailable" = "Les serveurs Apple ne sont pas disponibles actuellement. Veuillez réessayer plus tard."; +"iap.error.title" = "Erreur"; + +"agreement.trials.title" = "Termes et conditions des essais gratuits"; +"agreement.trials.message" = "Le paiement sera débité de votre compte Apple ID au moment de la confirmation de l'achat. L'abonnement se renouvelle automatiquement à moins qu'il ne soit annulé au moins 24 heures avant la fin de la période en cours. Votre compte sera débité du renouvellement dans les 24 heures précédant la fin de la période actuelle. Vous pouvez gérer et annuler vos abonnements en accédant aux paramètres du compte sur l'App Store après l'achat.\n\nCertains abonnements payants peuvent offrir un essai gratuit avant de débiter votre méthode de paiement. Si vous décidez de vous désabonner d'un abonnement payant avant que nous commencions à débiter votre méthode de paiement, annulez l'abonnement au moins 24 heures avant la fin de l'essai.\n\nLes essais gratuits ne sont disponibles que pour les nouveaux utilisateurs et sont à notre entière discrétion et si vous tentez de vous inscrire pour un autre essai gratuit, vous serez immédiatement débité des frais d'abonnement standards.\n\nNous nous réservons le droit de révoquer votre essai gratuit à tout moment.\n\nToute partie non utilisée de votre période d'essai gratuit sera abandonnée au moment de l'achat d'un abonnement.\n\nL'inscription constitue l'acceptation de ces termes et conditions."; +"agreement.message" = "Après l'essai gratuit de 7 jour, cet abonnement est renouvelé automatiquement pour %@, sauf s'il est annulé au moins 24 heures avant la fin de la période d'essai. Votre compte de l'identifiant Apple sera facturé pour le renouvellement 24 heures avant la fin de la période d'essai. Vous pouvez gérer et annuler vos abonnements en accédant aux paramètres de votre compte de l'App Store après l'achat. L'offre de l'essai de 7 jours est limité à une seule offre d'essai de 7 jours par utilisateur. Toute partie non utilisée d'une période d'essai (le cas échéant) sera abandonnée lorsque l'utilisateur achète une abonnement. Tous les prix comprennent les taxes locales applicables.\n\nL'abonnement signifie que vous acceptez les $1 et la $2."; +"agreement.trials.yearly.plan" = "an"; +"agreement.trials.monthly.plan" = "mois"; + +"agreement.message.tos" = "Conditions d'utilisation"; +"agreement.message.privacy" = "Politique de confidentialité"; + +"getstarted.buttons.buyaccount" = "Acheter un compte"; + +"gdpr.collect.data.title" = "Informations personnelles que nous collectons"; +"gdpr.collect.data.description" = "Adresse e-mail dans le but de gérer le compte et de protéger des abus."; +"gdpr.usage.data.title" = "Utilisation des informations personnelles que nous collectons"; +"gdpr.usage.data.description" = "L'adresse e-mail est utilisée pour envoyer les informations d'abonnement, les confirmation de paiement, la correspondance avec le client, et les offres promotionnelles de Private Internet Access uniquement."; +"gdpr.accept.button.title" = "Accepter et continuer"; + +"update.account.email.error" = "Échec de la modification de l'e-mail du compte"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings new file mode 100644 index 000000000..b60ca1b4e --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Conferma registrazione"; +"in_progress.message" = "Conferma dell'acquisto col sistema in corso. Potrebbe impiegare qualche secondo. Attendi."; +"in_progress.redeem.message" = "Conferma del PIN della tua carta col sistema in corso. Potrebbe impiegare qualche secondo. Attendi."; + +"success.title" = "Acquisto completato"; +"success.message_format" = "Grazie per la registrazione. Ti abbiamo inviato nome utente e password del tuo account all'indirizzo e-mail %@"; +"success.redeem.title" = "Carta riscossa"; +"success.redeem.message" = "Riceverai un'email a breve con nome utente e password.\n\nI tuoi dati d'accesso"; +"success.username.caption" = "Nome utente"; +"success.password.caption" = "Password"; +"success.submit" = "Inizia"; + +"failure.vc_title" = "Registrazione non riuscita"; +"failure.title" = "Errore di creazione account"; +"failure.message" = "Impossibile creare un account in questo momento. Riprova più tardi. \n\nRiaprendo l'app si riproverà a creare un account."; +"failure.purchase.sandbox.message" = "L'abbonamento del sandbox selezionato on è disponibile in produzione."; +"failure.redeem.invalid.title" = "PIN della carta non valido"; +"failure.redeem.invalid.message" = "Hai inserito un PIN della carta non valido. Riprova."; +"failure.redeem.claimed.title" = "Carta già riscattata"; +"failure.redeem.claimed.message" = "Questa carta è già stata riscattata da un altro account. Prova a inserire un PIN diverso."; +"failure.submit" = "INDIETRO"; + +"unreachable.vc_title" = "Errore"; +"unreachable.title" = "Ops!"; +"unreachable.message" = "Nessuna connessione Internet trovata. Verifica la connessione Internet e premi Riprova di seguito.\n\nPuoi tornare all'app più tardi per terminare il processo."; +"unreachable.submit" = "RIPROVA"; + +"purchase.uncredited.alert.message" = "Hai transazioni non accreditate. Vuoi recuperare i dati del tuo account?"; +"purchase.uncredited.alert.button.cancel" = "Annulla"; +"purchase.uncredited.alert.button.recover" = "Recupera account"; + +"purchase.trials.intro" = "Inizia la tua prova gratuita da 7 giorni"; +"purchase.trials.price.after" = "Poi a %@"; +"purchase.trials.money.back" = "Garanzia di rimborso entro 30 giorni"; +"purchase.trials.1year.protection" = "1 anno di privacy e protezione d'indentità"; +"purchase.trials.anonymous" = "Sfoglia anonimamente e nascondi il tuo IP."; +"purchase.trials.devices" = "Supporta 10 dispositivi alla volta"; +"purchase.trials.devices.description" = "Proteggi un massimo di 10 dispositivi alla volta."; +"purchase.trials.region" = "Connettiti facilmente a qualsiasi regione"; +"purchase.trials.servers" = "Oltre 3300 server in 32 Paesi"; +"purchase.trials.start" = "Inizia abbonamento"; +"purchase.trials.all.plans" = "Vedi tutti i piani disponibili"; + +"purchase.subscribe.now" = "Iscriviti ora"; + +// WALKTHROUGH + +"walkthrough.action.next" = "AVANTI"; +"walkthrough.action.done" = "FATTO"; +"walkthrough.action.skip" = "SALTA"; + +"walkthrough.page.1.title" = "Supporta 10 dispositivi alla volta"; +"walkthrough.page.1.description" = "Proteggi te stesso su un massimo di 10 dispositivi alla volta."; +"walkthrough.page.2.title" = "Connettiti facilmente a qualsiasi regione"; +"walkthrough.page.2.description" = "Con server in tutto il mondo, sei sempre protetto."; +"walkthrough.page.3.title" = "Proteggiti dalle pubblicità"; +"walkthrough.page.3.description" = "Abilitando il nostro Blocco dei contenuti non visualizzerai la pubblicità mentre navighi con Safari."; + +"share.data.buttons.accept" = "Accetta"; +"share.data.buttons.noThanks" = "No, grazie"; +"share.data.buttons.readMore" = "Leggi di più"; +"share.data.text.title" = "Aiutaci a migliorare il tuo servizio"; +"share.data.text.description" = "Per aiutarci a garantire le prestazioni di connessione del nostro servizio, puoi condividere in modo anonimo le tue statistiche di connessione con noi. Questi rapporti non contengono informazioni d'identificazione personale."; +"share.data.text.footer" = "Puoi sempre controllare questa funzione dalle tue impostazioni"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/UI.strings new file mode 100644 index 000000000..fc2c6c196 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versione %@ (%@)"; +"global.close" = "Chiudi"; +"global.ok" = "OK"; +"global.cancel" = "Annulla"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings new file mode 100644 index 000000000..197265683 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Accedi al tuo account"; +"login.username.placeholder" = "Nome utente (p1234567)"; +"login.password.placeholder" = "Password"; +"login.submit" = "ACCEDI"; +"login.restore.button" = "Non hai ancora ricevuto i dettagli dell'account?"; +"login.error.title" = "Accedi"; +"login.error.validation" = "Devi inserire un nome utente e una password."; +"login.error.unauthorized" = "Nome utente o password non valida"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Accedi mediante ricevuta d'acquisto"; +"login.magic.link.title" = "Accedi tramite il link magico della mail"; +"login.magic.link.response" = "Controlla la tua mail per ottenere il link d'accesso."; +"login.magic.link.send" = "Invia link"; +"login.magic.link.invalid.email" = "Indirizzo email non valido. Riprova."; + +"purchase.title" = "Seleziona un piano VPN"; +"purchase.subtitle" = "Garanzia di rimborso entro 30 giorni"; +"purchase.email.placeholder" = "Indirizzo email"; +"purchase.continue" = "Continua"; +"purchase.login.footer" = "Possiedi già un account?"; +"purchase.login.button" = "Accedi"; +"purchase.error.title" = "Acquista"; +"purchase.error.validation" = "Devi indicare un indirizzo e-mail."; +"purchase.error.connectivity.title" = "Errore di connessione"; +"purchase.error.connectivity.description" = "Non siamo in grado di stabilire l'accesso a una rete Internet privata. Ciò potrebbe essere dovuto a una scarsa qualità della rete o a un blocco dei nostri servizi nel tuo paese."; +"purchase.confirm.form.email" = "Inserisci il tuo indirizzo email"; +"purchase.confirm.plan" = "Stai acquistando il piano %@"; +"purchase.email.why" = "Per inviarti nome utente e password, abbiamo bisogno del tuo indirizzo email."; +"purchase.submit" = "Invia"; +"purchase.or" = "o"; + +"upgrade.header" = "Bentornato!"; +"upgrade.title" = "Per usare Private Internet Access, devi rinnovare l'abbonamento."; +"upgrade.renew.now" = "Rinnova adesso"; + + + +"redeem.title" = "Riscatta la carta regalo"; +"redeem.subtitle" = "Digita qui sotto il tuo indirizzo email e le %lu cifre del PIN della carta regalo o carta di prova."; +"redeem.email.placeholder" = "Indirizzo email"; +"redeem.submit" = "INVIA"; +"redeem.error.title" = "Riscatta"; +"redeem.error.code" = "Il codice dev'essere di %lu cifre."; +"redeem.error.allfields" = "Digita il tuo indirizzo email e PIN della carta."; +"redeem.accessibility.back" = "Indietro"; +"redeem.giftcard.placeholder" = "PIN carta regalo"; + +"plan.monthly.title" = "Mensile"; +"plan.yearly.title" = "Annuale"; +"plan.yearly.detail_format" = "%@%@ all'anno"; +"plan.price_format" = "%@ al mese"; +"plan.best_value" = "Valore migliore"; +"plan.accessibility.per_month" = "al mese"; + +"restore.title" = "Ripristina acquisto non accreditato"; +"restore.subtitle" = "Se hai acquistato un piano mediante questa app ma non hai ricevuto le tue credenziali, puoi inviarle nuovamente da qui.\nNon verrà effettuato alcun addebito durante la procedura."; +"restore.email.placeholder" = "Indirizzo email"; +"restore.submit" = "CONFERMA"; + +"iap.error.message.unavailable" = "Server Apple attualmente non disponibili. Riprova più tardi."; +"iap.error.title" = "Errore"; + +"agreement.trials.title" = "Termini e condizioni della prova gratuita"; +"agreement.trials.message" = "Il pagamento verrà addebitato sul tuo account ID Apple alla conferma dell'acquisto. L'abbonamento si rinnova automaticamente a meno che non venga annullato entro 24 ore dalla fine del periodo attuale. Il tuo account verrà addebitato per il rinnovo entro 24 ore dalla fine del periodo attuale. Puoi gestire e cancellare i tuoi abbonamenti dalle impostazioni dell'account sull'App Store dopo l'acquisto.\n\nAlcuni abbonamenti a pagamento possono offrire una prova gratuita prima di addebitare il metodo di pagamento. Se decidi di annullare l'iscrizione a un abbonamento a pagamento prima dell'addebito, dovrai annullarla entro 24 ore dalla scadenza della prova gratuita.\n\nLe prove gratuite sono disponibili solo per i nuovi utenti e sono a nostra esclusiva discrezione. In caso di registrazione per ottenere una prova gratuita aggiuntiva, l'addebito dell'importo standard dell'abbonamento verrà effettuato immediatamente.\n\nCi riserviamo il diritto di revocare la prova gratuita in qualsiasi momento.\n\nQualsiasi parte inutilizzata del periodo di prova gratuito andrà persa al momento dell'acquisto di un abbonamento.\n\nLa registrazione implica l'accettazione dei presenti termini e condizioni."; +"agreement.message" = "Dopo 7 giorni di prova gratuita, l'abbonamento si rinnova automaticamente per % @ a meno che non venga annullato entro 24 ore dalla fine del periodo di prova. Il tuo account ID Apple verrà addebitato per il rinnovo entro 24 ore dalla fine del periodo di prova. Puoi gestire e cancellare i tuoi abbonamenti andando sulle impostazioni del tuo account App Store dopo l'acquisto. L'offerta di prova di 7 giorni è limitata a un'unica offerta da 7 giorni per utente. Ogni parte inutilizzata di un periodo di prova gratuito, se offerto, andrà perduta quando l'utente acquista un abbonamento. Tutti i prezzi includono le tasse locali applicabili.\n\nLa registrazione implica l'accettazione di $1 e $2."; +"agreement.trials.yearly.plan" = "anno"; +"agreement.trials.monthly.plan" = "mese"; + +"agreement.message.tos" = "Termini di servizio"; +"agreement.message.privacy" = "Informativa sulla Privacy"; + +"getstarted.buttons.buyaccount" = "Acquista account"; + +"gdpr.collect.data.title" = "Dati personali da noi raccolti"; +"gdpr.collect.data.description" = "Indirizzo email ai fini di gestione dell'account e della protezione dall'uso improprio."; +"gdpr.usage.data.title" = "Usi delle informazioni personali da noi richieste"; +"gdpr.usage.data.description" = "L'indirizzo email viene utilizzato solo per inviare informazioni sull'abbonamento, conferme di pagamento, corrispondenza col cliente e offerte promozionali di Private Internet Access."; +"gdpr.accept.button.title" = "Accetta e continua"; + +"update.account.email.error" = "Modifica email account non riuscita"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings new file mode 100644 index 000000000..886508935 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "サインアップを確定"; +"in_progress.message" = "システムがご購入を確定しています。しばらく時間がかかることがありますので、そのままお待ちください。"; +"in_progress.redeem.message" = "システムがご購入を確定しています。しばらく時間がかかることがありますので、そのままお待ちください。"; + +"success.title" = "購入完了"; +"success.message_format" = "サインアップありがとうございます。アカウントのユーザー名とパスワードをお客様のメールアドレス(%@)に送信いたしました。"; +"success.redeem.title" = "カードの引き換えが完了しました"; +"success.redeem.message" = "ユーザーネームとパスワードを記載したメールがまもなく届きます。\n\nお客様のログイン詳細"; +"success.username.caption" = "ユーザー名"; +"success.password.caption" = "パスワード"; +"success.submit" = "始める"; + +"failure.vc_title" = "サインアップできませんでした"; +"failure.title" = "アカウントの作成に失敗しました"; +"failure.message" = "ただ今アカウントを作成できません。後ほどもう一度お試しください。\n\nアプリを再起動すると、アカウント作成が再試行されます。"; +"failure.purchase.sandbox.message" = "選択されたサンドボックスのサブスクリプションは生産中のため利用できません。"; +"failure.redeem.invalid.title" = "無効なカードPIN"; +"failure.redeem.invalid.message" = "無効なカードPINを入力したようです。もう一度お試しください。"; +"failure.redeem.claimed.title" = "すでに獲得されたカードです"; +"failure.redeem.claimed.message" = "このカードは、すでに別のアカウントが獲得したようです。別のPINを入力してください。"; +"failure.submit" = "戻る"; + +"unreachable.vc_title" = "エラー"; +"unreachable.title" = "おっと!"; +"unreachable.message" = "インターネット接続が見つかりません。インターネットに接続していることを確認してから下の再試行をタップしてください。\n\n後ほどアプリでこのプロセスを完了することができます。"; +"unreachable.submit" = "再試行"; + +"purchase.uncredited.alert.message" = "反映されていない取引があります。アカウントの詳細を回復しますか?"; +"purchase.uncredited.alert.button.cancel" = "キャンセル"; +"purchase.uncredited.alert.button.recover" = "アカウントを回復"; + +"purchase.trials.intro" = "7日間無料トライアルを開始"; +"purchase.trials.price.after" = "以後%@"; +"purchase.trials.money.back" = "30日間返金保証"; +"purchase.trials.1year.protection" = "1年間のプライバシーおよび個人情報の保護"; +"purchase.trials.anonymous" = "ウェブの匿名利用でIPを非表示にします。"; +"purchase.trials.devices" = "一度に10台の端末をサポート"; +"purchase.trials.devices.description" = "一度に最大10台の端末を保護して自分を守ることができます。"; +"purchase.trials.region" = "すべての地域に簡単に接続"; +"purchase.trials.servers" = "32か国の3300以上のサーバー"; +"purchase.trials.start" = "サブスクリプションを開始"; +"purchase.trials.all.plans" = "利用可能なプランをすべて見る"; + +"purchase.subscribe.now" = "今すぐ定期購読を購入"; + +// WALKTHROUGH + +"walkthrough.action.next" = "次へ"; +"walkthrough.action.done" = "完了"; +"walkthrough.action.skip" = "スキップ"; + +"walkthrough.page.1.title" = "一度に10台の端末をサポート"; +"walkthrough.page.1.description" = "一度に最大10台の端末を保護して自分を守ることができます。"; +"walkthrough.page.2.title" = "あらゆる地域に簡単に接続"; +"walkthrough.page.2.description" = "世界中にサーバがあるので、常に保護された状態でいることができます。"; +"walkthrough.page.3.title" = "広告から自分を守りましょう"; +"walkthrough.page.3.description" = "コンテンツブロッカーを有効にすると、Safariで広告表示をブロックできます。"; + +"share.data.buttons.accept" = "同意する"; +"share.data.buttons.noThanks" = "いいえ、結構です"; +"share.data.buttons.readMore" = "もっと読む"; +"share.data.text.title" = "弊社のサービス改善にご協力ください"; +"share.data.text.description" = "弊社のサービスの接続パフォーマンス確保にご協力いただくには、接続データを匿名で弊社と共有してください。これらのレポートには、個人を特定できる情報は含まれません。"; +"share.data.text.footer" = "これは、設定からいつでもコントロール可能です"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings new file mode 100644 index 000000000..1751458e6 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "バージョン%@ (%@)"; +"global.close" = "閉じる"; +"global.ok" = "OK"; +"global.cancel" = "キャンセル"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings new file mode 100644 index 000000000..98aa77a8f --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "アカウントにサインイン"; +"login.username.placeholder" = "ユーザー名 (p1234567)"; +"login.password.placeholder" = "パスワード"; +"login.submit" = "ログイン"; +"login.restore.button" = "アカウント詳細を受信しませんでしたか?"; +"login.error.title" = "ログイン"; +"login.error.validation" = "ユーザー名とパスワードを入力してください。"; +"login.error.unauthorized" = "ユーザー名またはパスワードが間違っています。"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "購入領収書を使用してログイン"; +"login.magic.link.title" = "魔法のメールリンクを使用してログイン"; +"login.magic.link.response" = "ログインリンクについては、メールを確認してください。"; +"login.magic.link.send" = "リンクを送信"; +"login.magic.link.invalid.email" = "無効なメールアドレス。もう一度お試しください。"; + +"purchase.title" = "VPNプランを選択"; +"purchase.subtitle" = "30日間返金保証"; +"purchase.email.placeholder" = "メールアドレス"; +"purchase.continue" = "続行"; +"purchase.login.footer" = "既にアカウントをお持ちですか?"; +"purchase.login.button" = "サインイン"; +"purchase.error.title" = "購入"; +"purchase.error.validation" = "必ずメールアドレスを入力してください。"; +"purchase.error.connectivity.title" = "接続エラー"; +"purchase.error.connectivity.description" = "Private Internet Accessに接続できませんでした。インターネットの接続が不安定、もしくはお住まいの国で当社サービスがブロックされている可能性があります。"; +"purchase.confirm.form.email" = "メールアドレスを入力してください"; +"purchase.confirm.plan" = "お客様は%@プランを購入しようとしています"; +"purchase.email.why" = "ユーザー名とパスワードを送信するためのメールアドレスを入力してください。"; +"purchase.submit" = "送信"; +"purchase.or" = "または"; + +"upgrade.header" = "お帰りなさい!"; +"upgrade.title" = "Private Internet Accessのご利用を継続するには、サブスクリプションを更新する必要があります。"; +"upgrade.renew.now" = "今すぐ更新"; + + + +"redeem.title" = "ギフトカード引換え"; +"redeem.subtitle" = "メールアドレスと、以下のギフトカードまたはトライアルカードの%lu桁のPINを入力してください。"; +"redeem.email.placeholder" = "メールアドレス"; +"redeem.submit" = "送信"; +"redeem.error.title" = "引換え"; +"redeem.error.code" = "コードは%lu桁でなければなりません。"; +"redeem.error.allfields" = "メールアドレスとカードのPINを入力してください。"; +"redeem.accessibility.back" = "戻る"; +"redeem.giftcard.placeholder" = "ギフトカードのPIN"; + +"plan.monthly.title" = "月間"; +"plan.yearly.title" = "年間"; +"plan.yearly.detail_format" = "年間%@%@"; +"plan.price_format" = "%@/月"; +"plan.best_value" = "最もお得"; +"plan.accessibility.per_month" = "月々"; + +"restore.title" = "追加されていない更新を復元"; +"restore.subtitle" = "このアプリでプランを購入した後、認証情報を受け取っていない方は、こちらから認証情報を再度送信することができます。この処理の実行中、課金は発生しません。"; +"restore.email.placeholder" = "メールアドレス"; +"restore.submit" = "確定"; + +"iap.error.message.unavailable" = "Appleサーバーが現在ご利用いただけません。後でもう一度お試しください。"; +"iap.error.title" = "エラー"; + +"agreement.trials.title" = "無料トライアル利用規約"; +"agreement.trials.message" = "ご購入確定時にお使いのApple IDアカウント支払額が請求されます。サブスクリプションは現在の期間が終了する24時間前までにキャンセルされない限り自動的に更新されます。更新料は現在の期間終了前の24時間以内にお使いのアカウントに請求されます。サブスクリプションはご購入後にApp Storeのアカウント設定からいつでも管理およびキャンセルすることができます。\n\n一部の有料サブスクリプションでは、ご希望の支払方法による請求が実施される前に無料トライアルが提供されている場合があります。ご選択の支払方法による請求が実施される前に有料サブスクリプションの解約をする場合は、無料トライアルが終了する24時間前までにサブスクリプションをキャンセルしてください。\n\n無料トライアルをご利用いただけるのは新規ユーザーのみとなり、無料トライアルを使用する目的で新たに追加のアカウントをサインアップした場合、弊社の裁量によって、通常のサブスクリプション料金が即時に請求されます。\n\n弊社は無料トライアル期間をいつでも無効にする権利を保持します。\n\nサブスクリプションご購入後、未使用分の無料トライアル期間は無効となります。\n\nサインアップすることで、$1と$2に同意したことになります。"; +"agreement.message" = "トライアル期間終了の少なくとも24時間前にキャンセルされない限り、7日間の無料トライアル後、この定期購読は自動的に%@で更新されます。更新料は、トライアル期間終了前の24時間以内にご利用のApple IDアカウントに請求されます。定期購読は、定期購読購入後にApp Storeアカウント設定から管理およびキャンセルすることができます。7日間のトライアルオファーは、ユーザー1人あたり1回の7日間トライアルに限られています。無料トライアルを利用した場合、無料トライアル期間の未使用分は、ユーザーが定期購読を購入した時点で無効となります。すべての料金には、適用可能な場合現地の消費税が含まれます。\n\nサインアップすることにより、$1および$2に同意したことになります。"; +"agreement.trials.yearly.plan" = "年"; +"agreement.trials.monthly.plan" = "月"; + +"agreement.message.tos" = "利用規約"; +"agreement.message.privacy" = "プライバシーポリシー"; + +"getstarted.buttons.buyaccount" = "アカウントを購入する"; + +"gdpr.collect.data.title" = "弊社が収集する個人情報"; +"gdpr.collect.data.description" = "メールアドレスは、アカウント管理、および乱用からの保護を目的とします。"; +"gdpr.usage.data.title" = "弊社により収集される個人情報の使用"; +"gdpr.usage.data.description" = "メールアドレスはサブスクリプション情報、お支払確認、お客様とのやり取り、およびPrivate Internet Accessのプロモーションオファーを送信するためにのみ使用されます。"; +"gdpr.accept.button.title" = "同意して続行する"; + +"update.account.email.error" = "アカウントのメールを変更できませんでした"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings new file mode 100644 index 000000000..cfd62453f --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "회원 가입 확인"; +"in_progress.message" = "저희 시스템에서 고객님의 구매를 확인하고 있습니다. 약간 시간이 소요될 수 있으므로 양해 부탁드립니다."; +"in_progress.redeem.message" = "저희 시스템에서 고객님의 카드 PIN을 확인하고 있습니다. 약간 시간이 소요될 수 있으므로 양해 부탁드립니다."; + +"success.title" = "구매 완료"; +"success.message_format" = "회원으로 가입해 주셔서 감사합니다. 계정 사용자명과 비밀번호를 귀하의 이메일 주소(%@)로 발송했습니다."; +"success.redeem.title" = "카드 사용 성공"; +"success.redeem.message" = "사용자 이름 및 비밀번호가 담긴 이메일을 곧 보내드리겠습니다.\n\n귀하의 로그인 정보"; +"success.username.caption" = "사용자 이름"; +"success.password.caption" = "비밀번호"; +"success.submit" = "시작하기"; + +"failure.vc_title" = "회원 가입 실패"; +"failure.title" = "계정 생성 실패"; +"failure.message" = "지금은 계정을 생성할 수 없습니다. 나중에 다시 시도해주십시오.\n\n 앱을 다시 열면 계정 생성을 다시 시도합니다."; +"failure.purchase.sandbox.message" = "선택하신 샌드박스 구독은 생산에 사용할 수 없습니다."; +"failure.redeem.invalid.title" = "유효하지 않은 카드 PIN"; +"failure.redeem.invalid.message" = "유효하지 않은 카드 PIN을 입력한 것 같습니다. 다시 시도하세요."; +"failure.redeem.claimed.title" = "이미 청구한 카드"; +"failure.redeem.claimed.message" = "이 카드는 이미 다른 계정에서 청구한 것 같습니다. 다른 PIN을 입력해 보세요."; +"failure.submit" = "뒤로"; + +"unreachable.vc_title" = "오류"; +"unreachable.title" = "앗!"; +"unreachable.message" = "인터넷에 연결되지 않았습니다. 인터넷에 연결되어 있는지 확인하신 후 아래에서 다시 시도를 누르십시오.\n\n나중에 앱에 다시 돌아와서 이 과정을 완료할 수 있습니다."; +"unreachable.submit" = "다시 시도"; + +"purchase.uncredited.alert.message" = "처리되지 않은 거래가 있습니다. 계정 정보를 복구하시겠습니까?"; +"purchase.uncredited.alert.button.cancel" = "취소"; +"purchase.uncredited.alert.button.recover" = "계정 복구"; + +"purchase.trials.intro" = "7일 무료 체험 시작"; +"purchase.trials.price.after" = "그 후 %@"; +"purchase.trials.money.back" = "30일 이내 환불 보장"; +"purchase.trials.1year.protection" = "1년간 프라이버시 및 신원 보호"; +"purchase.trials.anonymous" = "익명으로 검색하고 IP를 숨기세요."; +"purchase.trials.devices" = "동시에 10대의 장치 지원"; +"purchase.trials.devices.description" = "한 번에 최대 10대의 장치에서 보호를 받으세요."; +"purchase.trials.region" = "모든 지역에 쉽게 연결"; +"purchase.trials.servers" = "32개국 3300개 이상의 서버"; +"purchase.trials.start" = "구독 시작"; +"purchase.trials.all.plans" = "이용 가능한 모든 플랜 보기"; + +"purchase.subscribe.now" = "지금 구독"; + +// WALKTHROUGH + +"walkthrough.action.next" = "다음"; +"walkthrough.action.done" = "완료"; +"walkthrough.action.skip" = "건너뛰기"; + +"walkthrough.page.1.title" = "한 번의 10대의 장치 지원"; +"walkthrough.page.1.description" = "한 번에 최대 10대의 장치에서 보호를 받으세요."; +"walkthrough.page.2.title" = "모든 지역에 쉽게 연결"; +"walkthrough.page.2.description" = "전 세계에 있는 서버를 통해 언제나 보호를 받습니다."; +"walkthrough.page.3.title" = "광고로부터 보호"; +"walkthrough.page.3.description" = "Content Blocker를 활성화하면 Safari에서 광고가 표시되지 않습니다."; + +"share.data.buttons.accept" = "수락"; +"share.data.buttons.noThanks" = "아니요"; +"share.data.buttons.readMore" = "자세히 보기"; +"share.data.text.title" = "저희 서비스를 개선하도록 도와 주세요"; +"share.data.text.description" = "연결 상태를 저희와 익명으로 공유해 주시면 저희 서비스의 연결 성능을 개선하는 데 도움이 됩니다. 이 보고서에는 개인 식별 정보가 포함되지 않습니다."; +"share.data.text.footer" = "언제든지 설정에서 이 옵션을 관리할 수 있습니다."; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings new file mode 100644 index 000000000..1c9f1e509 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "버전 %@ (%@)"; +"global.close" = "닫기"; +"global.ok" = "확인"; +"global.cancel" = "취소"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings new file mode 100644 index 000000000..2d29b5f83 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "계정에 로그인"; +"login.username.placeholder" = "사용자 이름 (p1234567)"; +"login.password.placeholder" = "비밀번호"; +"login.submit" = "로그인"; +"login.restore.button" = "계정 정보를 받지 못하셨습니까?"; +"login.error.title" = "로그인"; +"login.error.validation" = "사용자 이름과 비밀번호를 입력하셔야 합니다."; +"login.error.unauthorized" = "사용자명 또는 비밀번호가 틀립니다."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "구매 영수증을 사용해 로그인"; +"login.magic.link.title" = "이메일 링크를 사용해 간편하게 로그인"; +"login.magic.link.response" = "로그인 링크가 담긴 이메일을 확인하세요."; +"login.magic.link.send" = "링크 보내기"; +"login.magic.link.invalid.email" = "이메일이 유효하지 않음. 다시 시도하세요."; + +"purchase.title" = "VPN 플랜 선택"; +"purchase.subtitle" = "30일 이내 환불 보장"; +"purchase.email.placeholder" = "이메일 주소"; +"purchase.continue" = "계속"; +"purchase.login.footer" = "이미 계정이 있으세요?"; +"purchase.login.button" = "로그인"; +"purchase.error.title" = "구매"; +"purchase.error.validation" = "이메일 주소를 입력하셔야 합니다."; +"purchase.error.connectivity.title" = "연결 실패"; +"purchase.error.connectivity.description" = "Private Internet Access에 접속할 수 없습니다. 인터넷 연결 상태가 좋지 않거나 귀하의 국가에서 당사의 서비스가 차단된 것 같습니다."; +"purchase.confirm.form.email" = "이메일 주소를 입력하세요"; +"purchase.confirm.plan" = "%@ 플랜을 구매합니다"; +"purchase.email.why" = "사용자 이름 및 비밀번호를 보내 드리면 고객님의 이메일 주소가 필요합니다."; +"purchase.submit" = "제출"; +"purchase.or" = "또는"; + +"upgrade.header" = "다시 오신 걸 환영합니다!"; +"upgrade.title" = "Private Internet Access를 사용하려면 구독을 갱신하셔야 합니다."; +"upgrade.renew.now" = "지금 갱신"; + + + +"redeem.title" = "기프트 카드 청구"; +"redeem.subtitle" = "기프트 카드 또는 체험 카드의 %lu자리 PIN과 이메일 주소를 입력하세요."; +"redeem.email.placeholder" = "이메일 주소"; +"redeem.submit" = "제출"; +"redeem.error.title" = "청구"; +"redeem.error.code" = "코드는 %lu자리 숫자여야 합니다."; +"redeem.error.allfields" = "이메일 및 카드 PIN을 입력하세요."; +"redeem.accessibility.back" = "뒤로"; +"redeem.giftcard.placeholder" = "기프트 카드 PIN"; + +"plan.monthly.title" = "월간"; +"plan.yearly.title" = "연간"; +"plan.yearly.detail_format" = "매년 %@%@"; +"plan.price_format" = "%@/월"; +"plan.best_value" = "최저가"; +"plan.accessibility.per_month" = "매월"; + +"restore.title" = "인정되지 않은 구매 항목 복원"; +"restore.subtitle" = "이 앱을 통해 요금 플랜을 구매하셨는데 자격 증명 정보를 받지 못하신 경우 이곳에서 다시 보내실 수 있습니다. 이 과정 중 요금이 부과되지 않습니다.\n"; +"restore.email.placeholder" = "이메일 주소"; +"restore.submit" = "확인"; + +"iap.error.message.unavailable" = "현재 Apple 서버를 이용할 수 없습니다. 나중에 다시 시도해주십시오."; +"iap.error.title" = "오류"; + +"agreement.trials.title" = "무료 체험 계약 조건"; +"agreement.trials.message" = "구매 확인 시 사용자의 Apple ID 계정으로 요금이 청구됩니다. 현재 기간이 종료하기 24시간 전에 취소하지 않으면 구독은 자동으로 갱신됩니다. 현재 기간이 종료하기 전 24시간 이내에 갱신 요금이 계정으로 청구됩니다. 구매 후 App Store의 계정 설정에서 구독을 관리하고 취소할 수 있습니다.\n\n일부 유료 구독은 사용자의 결제 수단으로 청구하기 전에 무료 체험을 제공할 수 있습니다. 결제 수단으로 청구가 시작되기 전에 유료 구독을 취소하려면, 무료 체험 기간이 종료하기 24시간 전에 구독을 취소하십시오.\n\n무료 체험은 신규 사용자만 이용할 수 있으며, 당사의 단독 재량으로 제공됩니다. 무료 체험을 추가로 이용하기 위해 가입한 경우 표준 구독 요금이 즉시 청구됩니다.\n\n당사는 언제든지 무료 체험을 철회할 권리를 보유합니다.\n\n구독 구매 시 무료 체험 기간의 미사용분은 소멸됩니다.\n\n가입 시 본 계약 조건에 동의하신 것으로 간주됩니다."; +"agreement.message" = "체험 기간이 종료하기 24시간 전에 구독을 취소하지 않으면, 7일 무료 체험 후 이 구독은 %@에 자동으로 갱신됩니다. 체험 기간이 종료하기 전 24시간 이내에 사용자의 Apple ID로 갱신 요금이 청구됩니다. 구매 후 App Store 계정으로 이동하여 구독을 관리하고 취소할 수 있습니다. 7일 체험 혜택은 사용자당 한 번으로 제한됩니다. 사용자가 구독을 구매할 경우 무료 체험 기간의 미사용분은 소멸됩니다. 모든 가격에는 현지에서 적용되는 판매세가 포함됩니다.\n\n가입 시 $1 및 $2에 동의하신 것으로 간주됩니다."; +"agreement.trials.yearly.plan" = "년"; +"agreement.trials.monthly.plan" = "개월"; + +"agreement.message.tos" = "서비스 약관"; +"agreement.message.privacy" = "개인정보 취급방침"; + +"getstarted.buttons.buyaccount" = "계정 구입"; + +"gdpr.collect.data.title" = "당사가 수집하는 개인 정보"; +"gdpr.collect.data.description" = "계정 관리 및 악용 방지를 위한 이메일 주소."; +"gdpr.usage.data.title" = "수집된 개인 정보의 사용"; +"gdpr.usage.data.description" = "이메일 주소는 구독 정보, 결제 확인, 고객 공지 사항 및 Private Internet Access 프로모션 정보를 보내는 데에만 사용됩니다."; +"gdpr.accept.button.title" = "동의 및 계속"; + +"update.account.email.error" = "계정 이메일을 수정하지 못했습니다"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings new file mode 100644 index 000000000..300d513ed --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Bekrefter registrering"; +"in_progress.message" = "Vi bekrefter kjøpet i systemet vårt. Dette kan ta litt tid."; +"in_progress.redeem.message" = "Vi bekrefter kort-PIN-en din i systemet vårt. Det kan ta et øyeblikk, så vennligst vent."; + +"success.title" = "Kjøp fullført"; +"success.message_format" = "Takk for at du registrerte deg. Vi har sendt deg kontonavnet og passordet ditt til e-postadressen din %@"; +"success.redeem.title" = "Kortet har blitt innløst"; +"success.redeem.message" = "Du mottar en e-post med brukernavn og passord.\n\nPåloggingsinformasjonen din"; +"success.username.caption" = "Brukernavn"; +"success.password.caption" = "Passord"; +"success.submit" = "Komme i gang"; + +"failure.vc_title" = "Registrering mislyktes"; +"failure.title" = "Kunne ikke opprette kontoen"; +"failure.message" = "Vi kunne ikke opprette en konto nå. Prøv på nytt senere.\n\nNår du åpner appen igjen, vil den prøve å opprette kontoen på nytt."; +"failure.purchase.sandbox.message" = "Det valgte sandboksabonnementet er ikke tilgjengelig i produksjon."; +"failure.redeem.invalid.title" = "Ugyldig kort-PIN"; +"failure.redeem.invalid.message" = "Ser ut til at du brukte en ugyldig kort-PIN. Prøv igjen"; +"failure.redeem.claimed.title" = "Kortet er allerede brukt"; +"failure.redeem.claimed.message" = "Ser ut til at kortet allerede er brukt av en annen konto. Du kan prøve med en annen PIN."; +"failure.submit" = "GÅ TILBAKE"; + +"unreachable.vc_title" = "Feil"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Ingen internettilkobling. Bekreft at du er koblet til Internett og trykk på Prøv igjen nedenfor.\n\nDu kan komme tilbake til appen senere for å fullføre prosessen."; +"unreachable.submit" = "PRØV PÅ NYTT"; + +"purchase.uncredited.alert.message" = "Du har ikke krediterte transaksjoner. Vil du gjenopprette kontoinformasjonen din?"; +"purchase.uncredited.alert.button.cancel" = "Abryt"; +"purchase.uncredited.alert.button.recover" = "Gjenopprett konto"; + +"purchase.trials.intro" = "Start din gratis 7-dagers prøveperiode"; +"purchase.trials.price.after" = "Deretter %@"; +"purchase.trials.money.back" = "30 dagers pengene-tilbake-garanti"; +"purchase.trials.1year.protection" = "Et års personverns- og identitetsbeskyttelse"; +"purchase.trials.anonymous" = "Surf anonymt og skjul IP-adressen din."; +"purchase.trials.devices" = "Støtter ti enheter om gangen"; +"purchase.trials.devices.description" = "Beskytt deg på opptil ti enheter samtidig."; +"purchase.trials.region" = "Koble til hvilken som helst region på en enkel måte"; +"purchase.trials.servers" = "Over 3300 servere i 32 land"; +"purchase.trials.start" = "Start abonnementet"; +"purchase.trials.all.plans" = "Vis alle tilgjengelige abonnement"; + +"purchase.subscribe.now" = "Abonner nå"; + +// WALKTHROUGH + +"walkthrough.action.next" = "NESTE"; +"walkthrough.action.done" = "FERDIG"; +"walkthrough.action.skip" = "HOPP OVER"; + +"walkthrough.page.1.title" = "Støtter ti enheter samtidig"; +"walkthrough.page.1.description" = "Beskytt deg på opptil ti enheter samtidig."; +"walkthrough.page.2.title" = "Koble til hvilken som helst region på en enkel måte"; +"walkthrough.page.2.description" = "Med serverer rundt om i hele verden, er du alltid beskyttet."; +"walkthrough.page.3.title" = "Beskytt deg selv mot reklame"; +"walkthrough.page.3.description" = "Aktivering av innholdsblokkereren sikrer at reklame ikke blir vist når du bruker Safari."; + +"share.data.buttons.accept" = "Godta"; +"share.data.buttons.noThanks" = "Nei takk"; +"share.data.buttons.readMore" = "Les mer"; +"share.data.text.title" = "Hjelp oss med å forbedre tjenesten vår"; +"share.data.text.description" = "For å hjelpe oss med å sikre tjenestens tilkoblingsytelse, kan du anonymt dele tilkoblingsstatistikken din med oss. Disse rapportene inkluderer informasjon som ikke er personlig identifiserbar."; +"share.data.text.footer" = "Du kan kontrollere dette fra innstillingene dine"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings new file mode 100644 index 000000000..5ccb0d7dc --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versjon %@ (%@)"; +"global.close" = "Lukk"; +"global.ok" = "OK"; +"global.cancel" = "Avbryt"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings new file mode 100644 index 000000000..80faed974 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Logg inn på kontoen din"; +"login.username.placeholder" = "Brukernavn (p1234567)"; +"login.password.placeholder" = "Passord"; +"login.submit" = "LOGG INN"; +"login.restore.button" = "Har du ikke fått kontodetaljene?"; +"login.error.title" = "Logg på"; +"login.error.validation" = "Du må oppgi et brukernavn og passord."; +"login.error.unauthorized" = "Brukernavnet eller passordet ditt er feil."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Logg på med kjøpsbevis"; +"login.magic.link.title" = "Pålogging med magisk e-postkobling"; +"login.magic.link.response" = "Sjekk e-posten din for å finne påloggingskoblingen."; +"login.magic.link.send" = "Send kobling"; +"login.magic.link.invalid.email" = "Ugyldig e-post. Prøv igjen."; + +"purchase.title" = "Velg et VPN-abonnement"; +"purchase.subtitle" = "30 dagers pengene-tilbake-garanti"; +"purchase.email.placeholder" = "E-postadresse"; +"purchase.continue" = "Fortsett"; +"purchase.login.footer" = "Har du allerede en konto?"; +"purchase.login.button" = "Logg inn"; +"purchase.error.title" = "Kjøp"; +"purchase.error.validation" = "Du må angi en e-postadresse."; +"purchase.error.connectivity.title" = "Tilkoblingsfeil"; +"purchase.error.connectivity.description" = "Vi kunne ikke nå Private Internet Access. Dette kan skyldes dårlig Internett eller at tjenesten vår er blokkert i landet ditt."; +"purchase.confirm.form.email" = "Angi e-postadressen din"; +"purchase.confirm.plan" = "Du kjøper %@-abonnementet"; +"purchase.email.why" = "Vi trenger e-posten din for å sende deg brukernavnet og passordet ditt."; +"purchase.submit" = "Send inn"; +"purchase.or" = "eller"; + +"upgrade.header" = "Velkommen tilbake!"; +"upgrade.title" = "For å bruke en privat internettilgang, må du fornye abonnementet ditt."; +"upgrade.renew.now" = "Forny nå"; + + + +"redeem.title" = "Løs inn gavekort"; +"redeem.subtitle" = "Angi e-postadressen og den %lu-sifrede PIN-koden fra gavekortet eller prøvekortet nedenfor."; +"redeem.email.placeholder" = "E-postadresse"; +"redeem.submit" = "SEND"; +"redeem.error.title" = "Løs inn"; +"redeem.error.code" = "Koden må bestå av %lu siffer."; +"redeem.error.allfields" = "Angi e-postadressen din og kortet PIN-kode."; +"redeem.accessibility.back" = "Tilbake"; +"redeem.giftcard.placeholder" = "PIN-kode for gavekort"; + +"plan.monthly.title" = "Månedlig"; +"plan.yearly.title" = "Årlig"; +"plan.yearly.detail_format" = "%@%@ per år"; +"plan.price_format" = "%@/mnd"; +"plan.best_value" = "Mest for pengene"; +"plan.accessibility.per_month" = "per måned"; + +"restore.title" = "Gjenopprett ukreditert kjøp"; +"restore.subtitle" = "Hvis du har kjøpt en plan via appen og ikke har mottatt opplysningene dine, kan du sende dem på nytt herfra.\nDu belastes ikke under denne prosessen."; +"restore.email.placeholder" = "E-postadresse"; +"restore.submit" = "BEKREFT"; + +"iap.error.message.unavailable" = "Apple-serverne er for øyeblikket ikke tilgjengelige. Prøv igjen senere."; +"iap.error.title" = "Feil"; + +"agreement.trials.title" = "Vilkår og betingelser for gratis prøveperiode"; +"agreement.trials.message" = "Betalingen belastes Apple ID-kontoen din når du bekrefter kjøpet. Abonnementet fornyes automatisk med mindre det kanselleres minst 24 timer før slutten av den inneværende perioden. Kontoen blir belastet for fornyelse innen 24 timer før slutten av den inneværende perioden. Du kan administrere og kansellere abonnementene dine ved besøke kontoinnstillingene på App Store etter kjøpet.\n\nEnkelte betalte abonnementer kan tilby en gratis prøveperiode før det belaster betalingsmetoden din. Hvis du bestemmer deg for å avslutte et betalt abonnement før vi begynner å belaste betalingsmetoden din, må du kansellere abonnementet minst 24 timer før prøveperioden er slutt.\n\nGratis prøveperioder er kun tilgjengelig for nye brukere og utføres etter vårt eget skjønn. Hvis du forsøker å registrere deg med flere gratis prøveperioder, blir du øyeblikkelig belastet standard abonnementsavgift.\n\nVi forbeholder oss retten til å tilbakekalle din gratis prøveperiode når som helst.\n\nEventuell ubrukt del av en gratis prøveperiode går tapt ved kjøpe av et abonnement.\n\nVed å registrere deg samtykker du til disse vilkårene og betingelsene."; +"agreement.message" = "Etter den gratis 7-dagers prøveperioden fornyes abonnementet automatisk for %@, med mindre det kanselleres minst 24 timer før slutten av prøveperioden. Din Apple ID-konto belastes for fornyingen innen 24 timer før slutten av prøveperioden. Du kan administrere og avbryte abonnementene dine ved å gå til App Store-kontoinnstillingene etter kjøp. Det 7-dagers prøvetilbudet er begrenset til én 7-dagers prøveperiode per bruker. Eventuell ubrukt tid av den gratis prøveperioden går tapt hvis brukeren kjøper et abonnement. Alle priser inkluderer gjeldende lokale avgifter.\n\nVed å signere godtar du $1 og $2."; +"agreement.trials.yearly.plan" = "år"; +"agreement.trials.monthly.plan" = "måned"; + +"agreement.message.tos" = "Tjenestevilkår"; +"agreement.message.privacy" = "REntingslinjer om personvern"; + +"getstarted.buttons.buyaccount" = "Kjøpskonto"; + +"gdpr.collect.data.title" = "Personlig informasjon vi tar vare på"; +"gdpr.collect.data.description" = "E-postadresse for kontoadministrasjon og beskyttelse mot misbruk."; +"gdpr.usage.data.title" = "Bruk av personlig informasjon samlet inn av oss"; +"gdpr.usage.data.description" = "E-postadresse blir kun brukt for å sende ut informasjon om abonnementet, betalingsbekreftelser, kundekorrespondanse og tilbud om privat internettilgang."; +"gdpr.accept.button.title" = "Godta og fortsett"; + +"update.account.email.error" = "Kunne ikke endre kontoens e-post"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings new file mode 100644 index 000000000..97c63fd93 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Aanmelding bevestigen"; +"in_progress.message" = "We zijn uw aankoop aan het verifiëren in ons systeem. Dit kan eventjes duren, daarom vragen we u vriendelijk om geduld."; +"in_progress.redeem.message" = "We zijn uw pincode aan het verifiëren in ons systeem. Dit kan eventjes duren, daarom vragen we u vriendelijk om geduld."; + +"success.title" = "Aankoop voltooid"; +"success.message_format" = "Bedankt voor uw aanmelding. We hebben de gebruikersnaam en het wachtwoord voor uw account naar het volgende e-mailadres gestuurd: %@"; +"success.redeem.title" = "Kaart ingewisseld"; +"success.redeem.message" = "U ontvangt zo een e-mail met uw gebruikersnaam en wachtwoord."; +"success.username.caption" = "Gebruikersnaam"; +"success.password.caption" = "Wachtwoord"; +"success.submit" = "Aan de slag"; + +"failure.vc_title" = "Aanmelden mislukt"; +"failure.title" = "Account aanmaken mislukt"; +"failure.message" = "We kunnen op dit moment geen account maken. Probeer het later opnieuw. \n\nAls u de app opnieuw opent, wordt opnieuw geprobeerd een account te maken."; +"failure.purchase.sandbox.message" = "Het geselecteerde sandbox-abonnement is niet beschikbaar in productie."; +"failure.redeem.invalid.title" = "Ongeldige pincode"; +"failure.redeem.invalid.message" = "U heeft een ongeldige pincode ingevoerd. Probeer het opnieuw."; +"failure.redeem.claimed.title" = "Kaart al geclaimd"; +"failure.redeem.claimed.message" = "Deze kaart is door een ander account geclaimd. Probeer een andere pincode."; +"failure.submit" = "GA TERUG"; + +"unreachable.vc_title" = "Fout"; +"unreachable.title" = "Oeps!"; +"unreachable.message" = "Geen internetverbinding gevonden. Controleer uw internetverbinding en probeer het hieronder opnieuw.\n\nU kunt later naar de app terugkeren om het proces te voltooien."; +"unreachable.submit" = "OPNIEUW PROBEREN"; + +"purchase.uncredited.alert.message" = "U heeft niet-gecrediteerde transacties. Wilt u uw accountgegevens herstellen?"; +"purchase.uncredited.alert.button.cancel" = "Annuleren"; +"purchase.uncredited.alert.button.recover" = "Account herstellen"; + +"purchase.trials.intro" = "Start je gratis proefabonnement van 7 dagen"; +"purchase.trials.price.after" = "Daarna %@"; +"purchase.trials.money.back" = "30 dagen lang niet-goed-geld-teruggarantie"; +"purchase.trials.1year.protection" = "1 jaar aan privacy- en identiteitsbescherming"; +"purchase.trials.anonymous" = "Browse anoniem en verberg uw ip."; +"purchase.trials.devices" = "Ondersteun tien apparaten tegelijk"; +"purchase.trials.devices.description" = "Bescherm uzelf op tien apparaten tegelijk."; +"purchase.trials.region" = "Maak eenvoudig verbinding met elke regio"; +"purchase.trials.servers" = "Meer dan 3300 servers in 32 landen"; +"purchase.trials.start" = "Abonnement starten"; +"purchase.trials.all.plans" = "Bekijk de beschikbare abonnementen"; + +"purchase.subscribe.now" = "Nu abonneren"; + +// WALKTHROUGH + +"walkthrough.action.next" = "VOLGENDE"; +"walkthrough.action.done" = "KLAAR"; +"walkthrough.action.skip" = "OVERSLAAN"; + +"walkthrough.page.1.title" = "Ondersteun tien apparaten tegelijk"; +"walkthrough.page.1.description" = "Bescherm uzelf op tien apparaten tegelijk."; +"walkthrough.page.2.title" = "Maak eenvoudig verbinding met elke regio"; +"walkthrough.page.2.description" = "Met servers over de hele wereld wordt u altijd beschermd."; +"walkthrough.page.3.title" = "Bescherm uzelf tegen advertenties"; +"walkthrough.page.3.description" = "Als u onze Content Blocker inschakelt, krijgt u geen advertenties meer te zien in Safari."; + +"share.data.buttons.accept" = "Accepteren"; +"share.data.buttons.noThanks" = "Nee, bedankt"; +"share.data.buttons.readMore" = "Meer informatie"; +"share.data.text.title" = "Help ons onze service te verbeteren"; +"share.data.text.description" = "Om ons te helpen de verbindingsprestaties van onze dienst te verbeteren, kunt u uw verbindingsstatistieken anoniem met ons delen. Deze rapporten bevatten geen persoonsgegevens."; +"share.data.text.footer" = "U kunt dit via de Instellingen beheren"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings new file mode 100644 index 000000000..0131eaac3 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versie %@ (%@)"; +"global.close" = "Sluiten"; +"global.ok" = "OK"; +"global.cancel" = "Annuleren"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings new file mode 100644 index 000000000..3c4007de5 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Aanmelden bij uw account"; +"login.username.placeholder" = "Gebruikersnaam (p1234567)"; +"login.password.placeholder" = "Wachtwoord"; +"login.submit" = "INLOGGEN"; +"login.restore.button" = "Geen accountgegevens ontvangen?"; +"login.error.title" = "Inloggen"; +"login.error.validation" = "U moet een gebruikersnaam en wachtwoord invoeren."; +"login.error.unauthorized" = "Uw gebruikersnaam of wachtwoord is onjuist."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Inloggen met aankoopbewijs"; +"login.magic.link.title" = "Log in met de magische link in uw e-mail"; +"login.magic.link.response" = "Controleer uw e-mail voor een inloglink."; +"login.magic.link.send" = "Link verzenden"; +"login.magic.link.invalid.email" = "Ongeldige e-mail. Probeer het opnieuw."; + +"purchase.title" = "Selecteer een VPN-abonnement"; +"purchase.subtitle" = "30 dagen lang niet-goed-geld-teruggarantie"; +"purchase.email.placeholder" = "E-mailadres"; +"purchase.continue" = "Doorgaan"; +"purchase.login.footer" = "Heeft u al een account?"; +"purchase.login.button" = "Aanmelden"; +"purchase.error.title" = "Kopen"; +"purchase.error.validation" = "U moet een e-mailadres invoeren"; +"purchase.error.connectivity.title" = "Verbindingsfout"; +"purchase.error.connectivity.description" = "We kunnen Private Internet Access niet bereiken. Dit kan komen door een slechte internetverbinding of omdat onze dienst in uw land is geblokkeerd."; +"purchase.confirm.form.email" = "Voer uw e-mailadres in"; +"purchase.confirm.plan" = "U koop het %@-abonnement"; +"purchase.email.why" = "We hebben uw e-mailadres nodig om uw gebruikersnaam en wachtwoord te versturen."; +"purchase.submit" = "Versturen"; +"purchase.or" = "of"; + +"upgrade.header" = "Welkom terug!"; +"upgrade.title" = "U moet uw abonnement vernieuwen om Private Internet Access te kunnen gebruiken."; +"upgrade.renew.now" = "Nu vernieuwen"; + + + +"redeem.title" = "Cadeaubon inwisselen"; +"redeem.subtitle" = "Voer uw e-mailadres en de %lu-cijferige pincode van uw cadeaubon of proefperiodekaart hieronder in."; +"redeem.email.placeholder" = "E-mailadres"; +"redeem.submit" = "VERSTUREN"; +"redeem.error.title" = "Inwisselen"; +"redeem.error.code" = "Code moet uit %lu getallen bestaan."; +"redeem.error.allfields" = "Voer uw e-mailadres en pincode in."; +"redeem.accessibility.back" = "Terug"; +"redeem.giftcard.placeholder" = "Pincode cadeaubon"; + +"plan.monthly.title" = "Maandelijks"; +"plan.yearly.title" = "Jaarlijks"; +"plan.yearly.detail_format" = "%@%@ per jaar"; +"plan.price_format" = "%@/ma"; +"plan.best_value" = "Beste waarde"; +"plan.accessibility.per_month" = "per maand"; + +"restore.title" = "Aankoop herstellen"; +"restore.subtitle" = "Als u een abonnement via deze app heeft aangeschaft en u heeft uw gegevens niet ontvangen, dan kunt u ze hier opnieuw verzenden. Er worden geen kosten in rekening gebracht tijdens dit proces."; +"restore.email.placeholder" = "E-mailadres"; +"restore.submit" = "BEVESTIGEN"; + +"iap.error.message.unavailable" = "De Apple-servers zijn momenteel niet beschikbaar. Probeer het later opnieuw."; +"iap.error.title" = "Fout"; + +"agreement.trials.title" = "Algemene voorwaarden gratis proefabonnementen"; +"agreement.trials.message" = "De betaling wordt bij de bevestiging van uw aankoop via uw Apple ID-account in rekening gebracht. Het abonnement wordt automatisch verlengd, tenzij het ten minste 24 uur voor het einde van de huidige periode wordt geannuleerd. De verlenging van uw account wordt binnen 24 uur voor het einde van de huidige periode in rekening gebracht. U kunt uw abonnementen beheren en annuleren door na de aankoop naar uw accountinstellingen in de App Store te gaan.\n\nBepaalde betaalde abonnementen kunnen een gratis proefabonnement aanbieden voordat er kosten in rekening worden gebracht. Als u zich wilt afmelden voor een betaald abonnement voordat we kosten in rekening brengen, moet u het abonnement ten minste 24 uur voor het einde van de gratis proefperiode annuleren.\n\nGratis proefabonnementen zijn alleen beschikbaar voor nieuwe gebruikers. Als u zich aanmeldt voor een aanvullend gratis proefabonnement worden onmiddellijk de standaard abonnementskosten in rekening gebracht.\n\nWij behouden ons het recht voor om uw gratis proefabonnement te allen tijde in te trekken.\n\nEen eventueel ongebruikt deel van uw gratis proefperiode vervalt bij aankoop van een abonnement.\n\nAls u zich aanmeldt, gaat u akkoord met deze algemene voorwaarden."; +"agreement.message" = "Na de gratis proefperiode van 7 dagen wordt het abonnement automatisch verlengd voor %@, tenzij u het ten minste 24 uur voor het einde van de proefperiode annuleert. De kosten voor de verlenging worden binnen 24 uur voor het einde van de proefperiode via uw Apple ID-account in rekening gebracht. U kunt uw abonnementen beheren en annuleren door na de aankoop naar uw accountinstellingen in de App Store te gaan. De proefperiode van 7 dagen is beperkt tot één proefperiode van 7 dagen per gebruiker. Een eventueel ongebruikt deel van uw gratis proefperiode vervalt bij aankoop van een abonnement. Alle prijzen zijn inclusief lokale omzetbelasting, indien van toepassing.\n\nAls u zich aanmeldt, gaat u akkoord met de $1 en het $2."; +"agreement.trials.yearly.plan" = "jaar"; +"agreement.trials.monthly.plan" = "maand"; + +"agreement.message.tos" = "Servicevoorwaarden"; +"agreement.message.privacy" = "Privacybeleid"; + +"getstarted.buttons.buyaccount" = "Account kopen"; + +"gdpr.collect.data.title" = "Persoonlijke informatie die we verzamelen"; +"gdpr.collect.data.description" = "E-mailadres voor accountbeheer en bescherming tegen misbruik."; +"gdpr.usage.data.title" = "Gebruik van de persoonlijke informatie die we verzamelen"; +"gdpr.usage.data.description" = "E-mailadres wordt alleen gebruikt voor het verzenden van abonnementsinformatie, betalingsbevestigingen, correspondentie met klanten en promotionele aanbiedingen van Private Internet Access."; +"gdpr.accept.button.title" = "Akkoord en doorgaan"; + +"update.account.email.error" = "Kan accountmail niet aanpassen"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings new file mode 100644 index 000000000..9922f65c3 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Potwierdź rejestrację"; +"in_progress.message" = "Potwierdzamy zakup w naszym systemie. Poczekaj spokojnie, bo to może trochę potrwać."; +"in_progress.redeem.message" = "Potwierdzamy Twój PIN karty w naszym systemie, TO może chwilę potrwać, więc prosimy o cierpliwość."; + +"success.title" = "Zakup zakończony"; +"success.message_format" = "Dziękujemy za rejestrację. Przesłaliśmy Twoją nazwę użytkownika i hasło na Twój adres e-mail: %@"; +"success.redeem.title" = "Karta została wymieniona"; +"success.redeem.message" = "Wkrótce otrzymasz e-mail z nazwą użytkownika i hasłem.\n\nTwoje dane do logowania"; +"success.username.caption" = "Nazwa użytkownika"; +"success.password.caption" = "Hasło"; +"success.submit" = "Rozpocznij"; + +"failure.vc_title" = "Rejestracja nie powiodła się"; +"failure.title" = "Błąd tworzenia konta"; +"failure.message" = "Obecnie nie możemy utworzyć konta. Spróbuj ponownie później."; +"failure.purchase.sandbox.message" = "Wybrana subskrypcja na piaskownicę (środowisko testowe) nie jest dostępna w produkcji."; +"failure.redeem.invalid.title" = "Nieprawidłowy PIN karty"; +"failure.redeem.invalid.message" = "Wygląda na to, ze wpisałeś nieprawidłowy PIN karty. Spróbuj ponownie."; +"failure.redeem.claimed.title" = "Karta już użyta"; +"failure.redeem.claimed.message" = "Wygląda na to, że ta karta została użyta na innym koncie. Możesz spróbować wpisać inny PIN."; +"failure.submit" = "WSTECZ"; + +"unreachable.vc_title" = "Błąd"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Nie znaleziono połączenia z internetem. Potwierdź, że masz połączenie z internetem i naciśnij „Spróbuj ponownie” poniżej..\n\nMożesz wrócić do aplikacji później, aby dokończyć proces."; +"unreachable.submit" = "SPRÓBUJ PONOWNIE"; + +"purchase.uncredited.alert.message" = "Masz nieuznane transakcje. Chcesz odzyskać dane swojego konta?"; +"purchase.uncredited.alert.button.cancel" = "Anuluj"; +"purchase.uncredited.alert.button.recover" = "Odzyskaj konto"; + +"purchase.trials.intro" = "Zacznij 7-dniowy bezpłatny okres próbny"; +"purchase.trials.price.after" = "Potem %@"; +"purchase.trials.money.back" = "30-dniowa gwarancja zwrotu pieniędzy"; +"purchase.trials.1year.protection" = "1 rok ochrony prywatności i tożsamości"; +"purchase.trials.anonymous" = "Przeglądaj sieć anonimowa i ukryj swoje IP"; +"purchase.trials.devices" = "Obsługa 10 urządzeń jednocześnie"; +"purchase.trials.devices.description" = "Ochrona na maksymalnie 10 urządzeniach jednocześnie."; +"purchase.trials.region" = "Łatwo połączysz się z dowolnym regionem"; +"purchase.trials.servers" = "Ponad 3300 serwerów w 32 krajach"; +"purchase.trials.start" = "Rozpocznij subskrypcję"; +"purchase.trials.all.plans" = "Sprawdź wszystkie dostępne plany"; + +"purchase.subscribe.now" = "Subskrybuj teraz"; + +// WALKTHROUGH + +"walkthrough.action.next" = "DALEJ"; +"walkthrough.action.done" = "GOTOWE"; +"walkthrough.action.skip" = "POMIŃ"; + +"walkthrough.page.1.title" = "Obsługa 10 urządzeń jednocześnie"; +"walkthrough.page.1.description" = "Ochrona na maksymalnie 10 urządzeniach jednocześnie."; +"walkthrough.page.2.title" = "Łatwo połączysz się z dowolnym regionem"; +"walkthrough.page.2.description" = "Dzięki serwerom na całym świecie zawsze jesteś pod ochroną."; +"walkthrough.page.3.title" = "Unikaj reklam"; +"walkthrough.page.3.description" = "Włączenie naszej Blokady zawartości chroni Cię przed wyświetlaniem reklam w Safari."; + +"share.data.buttons.accept" = "Akceptuj"; +"share.data.buttons.noThanks" = "Nie, dziękuję"; +"share.data.buttons.readMore" = "Dowiedz się więcej"; +"share.data.text.title" = "Prosimy o pomoc w ulepszeniu naszych usług"; +"share.data.text.description" = "Aby pomóc nam zapewnić najlepszą wydajność naszych usług, możesz anonimowo udostępniać nam swoje statystyki połączeń. Raporty te nie zawierają żadnych informacji umożliwiających identyfikację osób."; +"share.data.text.footer" = "Zawsze możesz to kontrolować w swoich ustawieniach"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings new file mode 100644 index 000000000..fccbc42bf --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Wersja %@ (%@)"; +"global.close" = "Zamknij"; +"global.ok" = "OK"; +"global.cancel" = "Anuluj"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings new file mode 100644 index 000000000..1af0054e2 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Zaloguj się na konto"; +"login.username.placeholder" = "Nazwa użytkownika (p1234567)"; +"login.password.placeholder" = "Hasło"; +"login.submit" = "ZALOGUJ"; +"login.restore.button" = "Nie dostałeś(-aś) Danych swojego konta?"; +"login.error.title" = "Zaloguj"; +"login.error.validation" = "Musisz podać nazwę użytkownika i hasło."; +"login.error.unauthorized" = "Twoja nazwa użytkownika i hasło są nieprawidłowe."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Zaloguj się, używając pokwitowania zakupu"; +"login.magic.link.title" = "Zaloguj się, używając sekretnego linku z e-maila"; +"login.magic.link.response" = "Link do logowania wysłaliśmy e-mailem,"; +"login.magic.link.send" = "Wyślij link"; +"login.magic.link.invalid.email" = "Nieprawidłowy e-mail. Spróbuj ponownie"; + +"purchase.title" = "Wybierz plan VPN"; +"purchase.subtitle" = "30-dniowej gwarancji zwrotu pieniędzy"; +"purchase.email.placeholder" = "Adres e-mail"; +"purchase.continue" = "Kontynuuj"; +"purchase.login.footer" = "Masz już konto?"; +"purchase.login.button" = "Zaloguj"; +"purchase.error.title" = "Zakup"; +"purchase.error.validation" = "Musisz podać adres e-mail."; +"purchase.error.connectivity.title" = "Błąd połączenia"; +"purchase.error.connectivity.description" = "Nie można połączyć z Private Internet Access. Może to być spowodowane słabym połączeniem z internetem lub nasza usługa może być zablokowana w Twoim kraju."; +"purchase.confirm.form.email" = "Podaj swój adres e-mail"; +"purchase.confirm.plan" = "Kupujesz abonament %@"; +"purchase.email.why" = "Twój e-mail jest nam potrzebny do przesłania Ci nazwy użytkownika i hasła,"; +"purchase.submit" = "Wyślij"; +"purchase.or" = "lub"; + +"upgrade.header" = "Witaj ponownie!"; +"upgrade.title" = "Aby korzystać z Private Internet Access, musisz odnowić swoją subskrypcję."; +"upgrade.renew.now" = "Odnów teraz"; + + + +"redeem.title" = "Wykorzystaj kartę podarunkową"; +"redeem.subtitle" = "Wpisz swój adres e-mail oraz %lu-cyfrowy PIN z karty podarunkowej lub karty próbnej poniżej."; +"redeem.email.placeholder" = "Adres e-mail"; +"redeem.submit" = "PRZEŚLIJ"; +"redeem.error.title" = "Wykorzystaj"; +"redeem.error.code" = "Kod musi składać się z %lu znaków numerycznych."; +"redeem.error.allfields" = "Podaj swój adres r-mail i PIN karty"; +"redeem.accessibility.back" = "Wstecz"; +"redeem.giftcard.placeholder" = "PIN karty upominkowej"; + +"plan.monthly.title" = "Miesięcznie"; +"plan.yearly.title" = "Rocznie"; +"plan.yearly.detail_format" = "%@%@ rocznie"; +"plan.price_format" = "%@/msc."; +"plan.best_value" = "Najlepsza wartość"; +"plan.accessibility.per_month" = "miesięcznie"; + +"restore.title" = "Przywróć pominięty zakup"; +"restore.subtitle" = "Jeśli kupił(a)ś abonament, korzystając z tej aplikacji, ale nie dostałe(a)ś danych logowania, możesz wysłać je ponownie stąd.\nOpłata nie zostanie za to pobrana za tę czynność"; +"restore.email.placeholder" = "Adres e-mail"; +"restore.submit" = "POTWIERDŹ"; + +"iap.error.message.unavailable" = "Serwery Apple'a są w tej chwili niedostępne. Spróbuj ponownie później."; +"iap.error.title" = "Błąd"; + +"agreement.trials.title" = "Regulamin korzystania z bezpłatnej wersji próbnej"; +"agreement.trials.message" = "Płatność zostanie pobrana z Twojego konta Apple ID z chwilą potwierdzenia zakupu. Subskrypcja odnawia się automatycznie, chyba że zostanie anulowana co najmniej 24 godziny przed końcem bieżącego okresu rozliczeniowego. Opłata za odnowienie subskrypcji zostanie pobrana w ciągu 24 godzin przed końcem bieżącego okresu. Możesz zarządzać subskrypcjami i je anulować, przechodząc do ustawień konta w App Store po dokonaniu zakupu.\n\nCzęść płatnych Subskrypcji może obejmować bezpłatną wersję próbną, z której możesz skorzystać przed naliczeniem opłaty. Jeśli postanowisz zrezygnować z płatnej subskrypcji przed rozpoczęciem naliczania opłat zgodnie z wybraną metodą płatności, anuluj subskrypcję co najmniej 24 godziny przed zakończeniem bezpłatnej wersji próbnej.\n\nBezpłatne wersje próbne są dostępne tylko dla nowych użytkowników i są przyznawane wyłącznie według naszego uznania, a w przypadku próby zarejestrowania w celu uzyskania dodatkowej bezpłatnej wersji próbnej, zostaniesz natychmiast obciążony standardową opłatą subskrypcyjną.\n\nRejestracja oznacza akceptację niniejszego regulaminu."; +"agreement.message" = "Po 7 dniach bezpłatnego okresu próbnego ta subskrypcja odnowi się automatycznie na %@, jeżeli nie zostanie anulowana co najmniej 24 godziny przed końcem okresu próbnego. Twoje konto Apple ID zostanie obciążone opłatą za odnowienie w ciągu 24 godzin przed końcem okresu próbnego. Możesz zarządzać swoimi subskrypcjami i je anulować, wchodząc po zakupie w ustawienia swojego konta w App Store Oferta 7-dniowego okresu próbnego jest ograniczona – każdemu użytkownikowi przysługuje jeden 7-dniowy okres próbny. Każda niewykorzystana część bezpłatnego okresu próbnego, jeśli zostanie zaoferowany, przepada wraz zakupem subskrypcji przez użytkownika. Wszystkie ceny zawierają obowiązujące lokalne podatki obrotowe.\n\nRejestracja oznacza akceptację artykułów. $1 i $2."; +"agreement.trials.yearly.plan" = "rok"; +"agreement.trials.monthly.plan" = "miesiąc"; + +"agreement.message.tos" = "Warunki użytkowania"; +"agreement.message.privacy" = "Zasady ochrony prywatności"; + +"getstarted.buttons.buyaccount" = "Zakup konto"; + +"gdpr.collect.data.title" = "Zbierane dane osobowe"; +"gdpr.collect.data.description" = "Adres e-mail do zarządzania kontem i ochrony przed nadużyciami."; +"gdpr.usage.data.title" = "Sposoby wykorzystania zbieranych przez nas danych osobowych"; +"gdpr.usage.data.description" = "Adres e-mail; używany go do wysyłania informacji o subskrypcji, potwierdzeń płatności, korespondencji z klientami i wysyłania ofert promocyjnych wyłącznie Private Internet Access"; +"gdpr.accept.button.title" = "Zaakceptuj i kontynuuj"; + +"update.account.email.error" = "Nie udało się zmienić adresu e-mail konta"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings new file mode 100644 index 000000000..5bcf7cb9a --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirme o registro"; +"in_progress.message" = "Confirmamos sua compra com o nosso sistema. Isso pode demorar um pouco. Por favor, aguarde."; +"in_progress.redeem.message" = "Estamos confirmando o PIN do seu cartão com o nosso sistema. Isso pode demorar um pouco. Por favor, aguarde."; + +"success.title" = "Compra Concluída"; +"success.message_format" = "Obrigado por se registrar conosco. Nós enviamos o nome de usuário e a senha da sua conta para o seu endereço de e-mail em %@"; +"success.redeem.title" = "Cartão resgatado com sucesso"; +"success.redeem.message" = "Você receberá um e-mail com seu nome de usuário e senha em breve.\n\nSeus dados de login"; +"success.username.caption" = "Nome de usuário"; +"success.password.caption" = "Senha"; +"success.submit" = "Comece Agora"; + +"failure.vc_title" = "Falha ao registrar"; +"failure.title" = "Falha ao Criar Conta"; +"failure.message" = "Não podemos criar uma conta neste momento. Tente novamente mais tarde.\n\nApós a reabertua do aplicativo, uma nova tentativa de criação de conta será realizada."; +"failure.purchase.sandbox.message" = "A assinatura da área restrita selecionada não está disponível em produção."; +"failure.redeem.invalid.title" = "PIN de cartão inválido"; +"failure.redeem.invalid.message" = "Parece que você inseriu um PIN de cartão inválido. Por favor, tente novamente."; +"failure.redeem.claimed.title" = "O cartão já foi resgatado"; +"failure.redeem.claimed.message" = "Parece que este cartão já foi resgatado por outra conta. Você pode tentar usar um PIN diferente."; +"failure.submit" = "VOLTAR"; + +"unreachable.vc_title" = "Erro"; +"unreachable.title" = "Ops!"; +"unreachable.message" = "Nenhuma conexão com a Internet encontrada. Confirme que você possui uma conexão com a Internet e pressione Tentar Novamente abaixo.\n\nVocê pode retornar ao aplicativo mais tarde para finalizar o processo."; +"unreachable.submit" = "TENTAR NOVAMENTE"; + +"purchase.uncredited.alert.message" = "Você tem transações não creditadas. Deseja recuperar os detalhes da sua conta?"; +"purchase.uncredited.alert.button.cancel" = "Cancelar"; +"purchase.uncredited.alert.button.recover" = "Recuperar conta"; + +"purchase.trials.intro" = "Comece sua avaliação gratuita de 7 dias"; +"purchase.trials.price.after" = "Em seguida, %@"; +"purchase.trials.money.back" = "Garantia do dinheiro de volta em até 30 dias"; +"purchase.trials.1year.protection" = "1 ano de proteção de privacidade e identidade"; +"purchase.trials.anonymous" = "Navegue anonimamente e oculte seu IP."; +"purchase.trials.devices" = "Suporte para 10 dispositivos ao mesmo tempo"; +"purchase.trials.devices.description" = "Proteja-se em até 10 dispositivos ao mesmo tempo."; +"purchase.trials.region" = "Conecte-se a qualquer região facilmente"; +"purchase.trials.servers" = "Mais de 3.300 servidores em 32 países"; +"purchase.trials.start" = "Iniciar assinatura"; +"purchase.trials.all.plans" = "Veja todos os planos disponíveis"; + +"purchase.subscribe.now" = "Assine agora"; + +// WALKTHROUGH + +"walkthrough.action.next" = "AVANÇAR"; +"walkthrough.action.done" = "CONCLUÍDO"; +"walkthrough.action.skip" = "PULAR"; + +"walkthrough.page.1.title" = "Suporte para 10 dispositivos ao mesmo tempo"; +"walkthrough.page.1.description" = "Proteja-se em até 10 dispositivos ao mesmo tempo."; +"walkthrough.page.2.title" = "Conecte-se a qualquer região facilmente"; +"walkthrough.page.2.description" = "Com servidores ao redor do mundo, você está sempre protegido."; +"walkthrough.page.3.title" = "Proteja-se contra propagandas"; +"walkthrough.page.3.description" = "A ativação do nosso Bloqueador de Conteúdo impede que anúncios sejam exibidos no Safari."; + +"share.data.buttons.accept" = "Aceitar"; +"share.data.buttons.noThanks" = "Não, obrigado"; +"share.data.buttons.readMore" = "Leia mais"; +"share.data.text.title" = "Ajude-nos a melhorar nosso serviço"; +"share.data.text.description" = "Para nos ajudar a garantir o desempenho da conexão de nosso serviço, você pode compartilhar anonimamente as estatísticas da sua conexão conosco. Esses relatórios não incluem nenhuma informação de identificação pessoal."; +"share.data.text.footer" = "Você sempre poderá controlar isso em suas configurações"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings new file mode 100644 index 000000000..32e6d7e28 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versão %@ (%@)"; +"global.close" = "Fechar"; +"global.ok" = "OK"; +"global.cancel" = "Cancelar"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings new file mode 100644 index 000000000..7ed6d1e85 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Entre na sua conta"; +"login.username.placeholder" = "Nome de usuário (p1234567)"; +"login.password.placeholder" = "Senha"; +"login.submit" = "ENTRAR"; +"login.restore.button" = "Não recebeu detalhes da conta?"; +"login.error.title" = "Entrar"; +"login.error.validation" = "Você deve inserir um nome de usuário e senha."; +"login.error.unauthorized" = "Seu nome de usuário ou senha está incorreto."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Faça login usando o recibo de compra"; +"login.magic.link.title" = "Faça login usando o link mágico enviado por e-mail"; +"login.magic.link.response" = "Veja se você recebeu por e-mail um link para fazer login."; +"login.magic.link.send" = "Enviar link"; +"login.magic.link.invalid.email" = "E-mail inválido. Tente novamente."; + +"purchase.title" = "Selecione um plano de VPN"; +"purchase.subtitle" = "Garantia do dinheiro de volta em até 30 dias"; +"purchase.email.placeholder" = "Endereço de e-mail"; +"purchase.continue" = "Continuar"; +"purchase.login.footer" = "Já tem uma conta?"; +"purchase.login.button" = "Faça login"; +"purchase.error.title" = "Comprar"; +"purchase.error.validation" = "Você precisa inserir um endereço de e-mail."; +"purchase.error.connectivity.title" = "Falha na conexão"; +"purchase.error.connectivity.description" = "Não conseguimos acessar o Private Internet Access. Isso pode ser devido a uma conexão de internet fraca ou o nosso serviço está bloqueado em seu país."; +"purchase.confirm.form.email" = "Insira seu endereço de e-mail"; +"purchase.confirm.plan" = "Você está adquirindo o plano %@"; +"purchase.email.why" = "Precisamos do seu e-mail para enviarmos seu nome de usuário e senha."; +"purchase.submit" = "Enviar"; +"purchase.or" = "ou"; + +"upgrade.header" = "Seja bem-vindo(a)!"; +"upgrade.title" = "Para usar a Private Internet Access, você precisará renovar sua assinatura."; +"upgrade.renew.now" = "Renovar agora"; + + + +"redeem.title" = "Resgatar cartão-presente"; +"redeem.subtitle" = "Digite o seu endereço de e-mail e o PIN de %lu dígitos do seu cartão-presente ou cartão de teste abaixo."; +"redeem.email.placeholder" = "Endereço de e-mail"; +"redeem.submit" = "ENVIAR"; +"redeem.error.title" = "Resgatar"; +"redeem.error.code" = "O código precisa ter %lu dígitos numéricos."; +"redeem.error.allfields" = "Digite o seu e-mail e PIN do cartão."; +"redeem.accessibility.back" = "Voltar"; +"redeem.giftcard.placeholder" = "PIN do cartão-presente"; + +"plan.monthly.title" = "Mensal"; +"plan.yearly.title" = "Anual"; +"plan.yearly.detail_format" = "%@%@ por ano"; +"plan.price_format" = "%@/mês"; +"plan.best_value" = "Melhor valor"; +"plan.accessibility.per_month" = "por mês"; + +"restore.title" = "Restaurar compra não creditada"; +"restore.subtitle" = "Se você adquiriu um plano por este aplicativo e não recebeu as suas credenciais, você pode enviá-las novamente por aqui. Você não será cobrado durante esse processo."; +"restore.email.placeholder" = "Endereço de e-mail"; +"restore.submit" = "CONFIRMAR"; + +"iap.error.message.unavailable" = "Servidores da Apple indisponíveis no momento. Tente novamente mais tarde."; +"iap.error.title" = "Erro"; + +"agreement.trials.title" = "Termos e condições das avaliações gratuitas"; +"agreement.trials.message" = "O pagamento será cobrado na sua conta do ID Apple no ato da confirmação da compra. A assinatura será renovada automaticamente, a não ser que ela seja cancelada, pelo menos, 24 horas antes do fim do período atual. O valor da renovação será debitado na sua conta em até 24 horas antes do término do período da atual. Você pode gerenciar e cancelar suas assinaturas nos ajustes da conta na App Store após a compra.\n\nCertas assinaturas pagas podem oferecer uma avaliação gratuita antes da cobrança do pagamento. Se você decidir cancelar uma Assinatura Paga antes de começarmos a cobrar por ela, cancele-a, pelo menos, 24 horas antes do término da avaliação gratuita.\n\nAs avaliações gratuitas estão disponíveis apenas para novos usuários, e são a nosso critério. Se tentar se registrar para uma avaliação gratuita adicional, você será cobrado imediatamente com a Taxa de Assinatura padrão.\n\nReservamo-nos o direito de revogar sua avaliação gratuita a qualquer momento.\n\nQualquer parte não utilizada do período da sua avaliação gratuita será perdida após a compra de uma assinatura.\n\nO registro constitui da aceitação dos termos e condições."; +"agreement.message" = "Após os 7 dias da avaliação gratuita, a assinatura será renovada automaticamente por %@, a não ser que ela seja cancelada, pelo menos, 24 horas antes do término do período de avaliação. O valor da renovação será debitado da conta do seu ID Apple em até 24 horas antes do término do período de avaliação. Você pode gerenciar e cancelar suas assinaturas nos ajustes da conta da App Store após a compra. A oferta de avaliação de 7 dias é limitada a uma oferta de avaliação de 7 dias por usuário. Qualquer parte não utilizada do período de avaliação gratuita, se oferecida, será perdida após a aquisição de uma assinatura. Todos os preços incluem impostos de vendas locais aplicáveis.\n\nO registro constitui da aceitação dos $1 e da $2."; +"agreement.trials.yearly.plan" = "ano"; +"agreement.trials.monthly.plan" = "mês"; + +"agreement.message.tos" = "Termos de Serviço"; +"agreement.message.privacy" = "Política de Privacidade"; + +"getstarted.buttons.buyaccount" = "Comprar conta"; + +"gdpr.collect.data.title" = "Informações pessoais que coletamos"; +"gdpr.collect.data.description" = "Endereço de e-mail para gerenciamento de conta e proteção contra abuso."; +"gdpr.usage.data.title" = "Uso de informações pessoais coletadas por nós"; +"gdpr.usage.data.description" = "O endereço de e-mail é utilizado apenas para enviar informação de assinatura, confirmações de pagamento, correspondência com clientes e ofertas promocionais do Private Internet Access."; +"gdpr.accept.button.title" = "Concordar e continuar"; + +"update.account.email.error" = "Falha ao modificar o e-mail da conta"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings new file mode 100644 index 000000000..9f032f794 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Подтверждение регистрации"; +"in_progress.message" = "Мы проверяем вашу покупку в системе. На это может понадобиться время, так что оставайтесь с нами."; +"in_progress.redeem.message" = "Мы подтверждаем ваш PIN-код в системе. Это займет какое-то время, подождите немного."; + +"success.title" = "Покупка завершена"; +"success.message_format" = "Спасибо за регистрацию. Мы отправили имя пользователя и пароль на адрес электронной почты %@"; +"success.redeem.title" = "Карта успешно использована"; +"success.redeem.message" = "Также вы получите эл. письмо с именем пользователя и паролем.\n\nВаши учетные данные"; +"success.username.caption" = "Имя пользователя"; +"success.password.caption" = "Пароль"; +"success.submit" = "Начать"; + +"failure.vc_title" = "Ошибка регистрации"; +"failure.title" = "Сбой создания учетной записи"; +"failure.message" = "Нам не удалось создать учетную запись. Повторите попытку позже.\nПри повторном открытии приложения создание учетной записи будет возобновлено."; +"failure.purchase.sandbox.message" = "Выбранная подписка на «песочницу» недоступна в производственной среде."; +"failure.redeem.invalid.title" = "Неверный PIN-код карты"; +"failure.redeem.invalid.message" = "Похоже, вы ввели неверный PIN-код карты. Попробуйте еще раз."; +"failure.redeem.claimed.title" = "Карта уже использована"; +"failure.redeem.claimed.message" = "Похоже, эту карту уже использовали с другой учетной записи. Попробуйте ввести другой PIN."; +"failure.submit" = "ВОЗВРАТ"; + +"unreachable.vc_title" = "Ошибка"; +"unreachable.title" = "Ой!"; +"unreachable.message" = "Интернет-соединение не найдено. Пожалуйста, убедитесь, что у вас есть подключение к Интернету, и повторите попытку позже.\n\nМожно вернуться в приложение позже и завершить процесс."; +"unreachable.submit" = "ПОВТОРИТЬ"; + +"purchase.uncredited.alert.message" = "У вас есть непроведенные транзакции. Хотите восстановить данные своей учетной записи?"; +"purchase.uncredited.alert.button.cancel" = "Отмена"; +"purchase.uncredited.alert.button.recover" = "Восстановить учетную запись"; + +"purchase.trials.intro" = "Начните 7-дневную бесплатную пробу"; +"purchase.trials.price.after" = "После этого %@"; +"purchase.trials.money.back" = "30-дневная гарантия возврата денег"; +"purchase.trials.1year.protection" = "1 год защиты конфиденциальности и личных данных"; +"purchase.trials.anonymous" = "Пользуйтесь Интернетом анонимно и скрывайте свой IP-адрес."; +"purchase.trials.devices" = "Поддержка сразу 10 устройств"; +"purchase.trials.devices.description" = "Защищайте себя на нескольких устройствах одновременно (до 10)."; +"purchase.trials.region" = "Простое подключение к любому региону"; +"purchase.trials.servers" = "Более 3300 серверов в 32 странах"; +"purchase.trials.start" = "Запустить подписку."; +"purchase.trials.all.plans" = "Смотреть все доступные планы"; + +"purchase.subscribe.now" = "Подписаться"; + +// WALKTHROUGH + +"walkthrough.action.next" = "ДАЛЕЕ"; +"walkthrough.action.done" = "ГОТОВО"; +"walkthrough.action.skip" = "ПРОПУСК"; + +"walkthrough.page.1.title" = "Поддержка 10 устройств одновременно"; +"walkthrough.page.1.description" = "Защищайте себя на нескольких устройствах одновременно (до 10)."; +"walkthrough.page.2.title" = "Простое подключение к любому региону"; +"walkthrough.page.2.description" = "У нас есть серверы по всему миру, так что вы всегда будете под защитой."; +"walkthrough.page.3.title" = "Защита от рекламы"; +"walkthrough.page.3.description" = "Активация нашего правила блокирования контента препятствует отображению рекламы в Safari."; + +"share.data.buttons.accept" = "Принять"; +"share.data.buttons.noThanks" = "Спасибо, не надо"; +"share.data.buttons.readMore" = "Подробнее"; +"share.data.text.title" = "Помогите нам сделать нашу службу еще лучше"; +"share.data.text.description" = "Вы можете анонимно делиться с нами своей статистикой соединения, чтобы помочь нам обеспечить производительность подключения нашей службы. Эти отчеты не включают какую-либо личную информацию."; +"share.data.text.footer" = "Вы всегда можете управлять этим параметром через настройки"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings new file mode 100644 index 000000000..2d1416365 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Версия %@ (%@)"; +"global.close" = "Закрыть"; +"global.ok" = "ОК"; +"global.cancel" = "Отмена"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings new file mode 100644 index 000000000..cd0684978 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Войдите в свою учетную запсь"; +"login.username.placeholder" = "Имя пользователя (p1234567)"; +"login.password.placeholder" = "Пароль"; +"login.submit" = "ВХОД"; +"login.restore.button" = "Не получили данные учетной записи?"; +"login.error.title" = "Войти"; +"login.error.validation" = "Нужно ввести имя пользователя и пароль."; +"login.error.unauthorized" = "Неправильное имя пользователя или пароль."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Выполните вход по квитанции о покупке"; +"login.magic.link.title" = "Войти через волшебную ссылку из письма"; +"login.magic.link.response" = "Поищите ссылку для входа в письме."; +"login.magic.link.send" = "Отправить ссылку"; +"login.magic.link.invalid.email" = "Недействительный эл. адрес. Повторите попытку."; + +"purchase.title" = "Выберите план VPN"; +"purchase.subtitle" = "30-дневная гарантия возврата денег"; +"purchase.email.placeholder" = "Адрес эл. почты"; +"purchase.continue" = "Продолжить"; +"purchase.login.footer" = "Уже есть учетная запись?"; +"purchase.login.button" = "Вход"; +"purchase.error.title" = "Купить"; +"purchase.error.validation" = "Укажите адрес эл. почты."; +"purchase.error.connectivity.title" = "Ошибка подключения"; +"purchase.error.connectivity.description" = "Не удалось подключиться к Private Internet Access. Это может быть из-за плохого качества соединения с Интернетом, или наша служба заблокирована в вашей стране."; +"purchase.confirm.form.email" = "Введите свой адрес эл. почты"; +"purchase.confirm.plan" = "Вы приобретаете план «%@»"; +"purchase.email.why" = "Нам нужен ваш электронный адрес, чтобы мы могли прислать вам имя пользователя и пароль."; +"purchase.submit" = "Отправить"; +"purchase.or" = "или"; + +"upgrade.header" = "С возвращением!"; +"upgrade.title" = "Чтобы пользоваться Private Internet Access, вам необходимо продлить подписку."; +"upgrade.renew.now" = "Продлить"; + + + +"redeem.title" = "Исп-ть подарочную карту"; +"redeem.subtitle" = "Введите свой адрес эл. почты и %lu-зн. PIN-код с подарочной или триальной карты."; +"redeem.email.placeholder" = "Адрес эл. почты"; +"redeem.submit" = "ОТПРАВИТЬ"; +"redeem.error.title" = "Использовать"; +"redeem.error.code" = "В коде должно быть %lu цифр(ы)."; +"redeem.error.allfields" = "Введите свой эл. адрес и PIN-код карты"; +"redeem.accessibility.back" = "Назад"; +"redeem.giftcard.placeholder" = "PIN-код подарочной карты"; + +"plan.monthly.title" = "Ежемесячно"; +"plan.yearly.title" = "Ежегодно"; +"plan.yearly.detail_format" = "%@%@ в год"; +"plan.price_format" = "%@/мес."; +"plan.best_value" = "Максимальная выгода"; +"plan.accessibility.per_month" = "в месяц"; + +"restore.title" = "Восстановить непроведенную покупку"; +"restore.subtitle" = "Если вы купили план через это приложение и не получили учетных данных, вы можете повторно отправить их отсюда. За эту процедуру не взимается плата."; +"restore.email.placeholder" = "Адрес электронной почты"; +"restore.submit" = "ПОДТВЕРДИТЬ"; + +"iap.error.message.unavailable" = "Серверы Apple временно недоступны. Повторите попытку позже."; +"iap.error.title" = "Ошибка"; + +"agreement.trials.title" = "Положения и условия бесплатного пробного пользования"; +"agreement.trials.message" = "Платеж списывается со счета вашего Apple ID при подтверждении покупки. Подписка продлевается автоматически, если не отменить ее по меньшей мере за 24 часа до окончания текущего периода. Плата за продление подписки будет списана со счета вашей учетной записи в течение 24 часов до окончания текущего периода. Для управления подписками, в том числе их отмены, после покупки перейдите в настройки учетной записи в App Store.\n\nНекоторые платные подписки могут предлагать бесплатное пробное пользование перед тем, как списывать средства с использованием указанного вами способа оплаты. Если вы решите отменить платную подписку до того, как мы начнем списывать средства с использованием указанного вами способа оплаты, сделайте это по меньшей мере за 24 часа до окончания бесплатного пробного периода.\n\nБесплатное пробное пользование доступно только для новых пользователей и предлагается по нашему единоличному усмотрению, и если вы попытаетесь зарегистрироваться для участия в дополнительном бесплатном пробном пользовании, с вас будет незамедлительно списана стандартная стоимость подписки.\n\nМы оставляем за собой право в любое время прервать ваше бесплатное пробное пользование.\n\nНеиспользованная часть бесплатного пробного периода сгорает после приобретения подписки.\n\nЗарегистрировавшись, вы тем самым принимаете настоящие положения и условия."; +"agreement.message" = "После завершения 7-дневного бесплатного пробного периода подписка автоматически продлевается на %@, если не отменить ее по меньшей мере за 24 часа до окончания текущего периода. Плата за продление подписки будет списана со счета вашей учетной записи в течение 24 часов до окончания текущего периода. Для управления подписками, в том числе их отмены, после покупки перейдите в настройки учетной записи в App Store. 7-дневное пробное пользование предлагается каждому пользователю только 1 раз. Неиспользованная часть бесплатного пробного периода сгорает после приобретения подписки. Цена указывается с учетом местных налогов на продажу.\n\nРегистрируясь, вы тем самым принимаете списание с вашего счета сумм в $1 и $2 доллара США."; +"agreement.trials.yearly.plan" = "год"; +"agreement.trials.monthly.plan" = "месяц"; + +"agreement.message.tos" = "Условия использования"; +"agreement.message.privacy" = "Политика конфиденциальности"; + +"getstarted.buttons.buyaccount" = "Приобрести учетную запись"; + +"gdpr.collect.data.title" = "Личная информация, которую мы собираем"; +"gdpr.collect.data.description" = "Адрес эл. почты используется в целях управления учетной записью и защиты от злоупотреблений."; +"gdpr.usage.data.title" = "Использование собираемой нами личной информации"; +"gdpr.usage.data.description" = "Адрес эл. почты используется исключительно для отправки информации о подписке, подтверждений оплаты, переписки с пользователем и отправки акционных предложений Private Internet Access."; +"gdpr.accept.button.title" = "Принять и продолжить"; + +"update.account.email.error" = "Не удалось изменить эл. адрес учетной записи"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings new file mode 100644 index 000000000..520a4ea39 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "ยืนยันการสมัคร"; +"in_progress.message" = "เรากำลังยืนยันการซื้อของคุณกับระบบของเรา กรุณารอสักครู่"; +"in_progress.redeem.message" = "เรากำลังยืนยัน PIN การ์ดของคุณกับระบบของเรา กรุณารอสักครู่"; + +"success.title" = "ซื้อสำเร็จ"; +"success.message_format" = "ขอบคุณที่สมัครสมาชิกกับเรา เราได้ส่งชื่อผู้ใช้และรหัสผ่านไปยังอีเมลของคุณแล้วที่ %@"; +"success.redeem.title" = "คืนบัตรเสร็จสมบูรณ์!"; +"success.redeem.message" = "คุณจะได้รับอีเมลพร้อมชื่อผู้ใช้และรหัสผ่านในไม่ช้า\n\nข้อมูลการล็อกอิน"; +"success.username.caption" = "ชื่อผู้ใช้"; +"success.password.caption" = "รหัสผ่าน"; +"success.submit" = "เริ่มใช้งาน"; + +"failure.vc_title" = "การสมัครล้มเหลว"; +"failure.title" = "สร้างบัญชีผู้ใช้ไม่สำเร็จ"; +"failure.message" = "เราไม่สามารถสร้างบัญชีได้ในขณะนี้ กรุณาลองใหม่อีกครั้งภายหลัง การปิดเปิดแอปใหม่จะเป็นการพยายามสร้างบัญชีใหม่"; +"failure.purchase.sandbox.message" = "ไม่มีระบบสมาชิก Sandbox ที่คุณเลือกอยู่ในการผลิต"; +"failure.redeem.invalid.title" = "PIN การ์ดไม่ถูกต้อง"; +"failure.redeem.invalid.message" = "ดูเหมือนว่าคุณใส่ PIN การ์ดไม่ถูกต้อง กรุณาลองใหม่"; +"failure.redeem.claimed.title" = "บัตรมีการใช้สิทธิ์แล้ว"; +"failure.redeem.claimed.message" = "ดูเหมือนว่าบัตรนี้มีการใช้สิทธิ์แล้วโดยบัญชีอื่น กรุณาลองใส่ PIN อื่น"; +"failure.submit" = "ย้อนกลับ"; + +"unreachable.vc_title" = "ข้อผิดพลาด"; +"unreachable.title" = "อุ๊ปส์!"; +"unreachable.message" = "ไม่พบการเชื่อมต่ออินเทอร์เน็ต กรุณายืนยันว่าคุณมีการเชื่อมต่ออินเทอร์เน็ตแล้วกดลองอีกครั้งด้านล่างนี้\n\nคุณสามารถกลับมาใหม่ในภายหลังเพื่อดำเนินการต่อให้เสร็จ"; +"unreachable.submit" = "ลองใหม่"; + +"purchase.uncredited.alert.message" = "คุณได้ยกเลิกการทำธุรกรรมแล้ว คุณต้องการกู้คืนรายละเอียดบัญชีหรือไม่"; +"purchase.uncredited.alert.button.cancel" = "ยกเลิก"; +"purchase.uncredited.alert.button.recover" = "กู้คืนบัญชี"; + +"purchase.trials.intro" = "เริ่มทดลองใช้ฟรี 7 วัน"; +"purchase.trials.price.after" = "จากนั้น %@"; +"purchase.trials.money.back" = "รับประกันการคืนเงินภายใน 30 วัน"; +"purchase.trials.1year.protection" = "การป้องกันข้อมูลประจำตัวและความเป็นส่วนตัว 1 ปี"; +"purchase.trials.anonymous" = "เรียกดูโดยไม่ระบุชื่อและซ่อน ip ของคุณ"; +"purchase.trials.devices" = "รับรองอุปกรณ์ 10 เครื่องในเวลาเดียวกัน"; +"purchase.trials.devices.description" = "ปกป้องตัวคุณบนอุปกรณ์ถึง 10 เครื่องในเวลาเดียวกัน"; +"purchase.trials.region" = "เชื่อมต่อไปยังภูมิภาคใดก็ตามได้อย่างง่ายดาย"; +"purchase.trials.servers" = "กว่า 3300 เซิร์ฟเวอร์ใน 32 ประเทศ"; +"purchase.trials.start" = "เริ่มการเป็นสมาชิก"; +"purchase.trials.all.plans" = "ดูแผนที่มีทั้งหมด"; + +"purchase.subscribe.now" = "สมัครสมาชิกตอนนี้"; + +// WALKTHROUGH + +"walkthrough.action.next" = "ถัดไป"; +"walkthrough.action.done" = "เสร็จสิ้น"; +"walkthrough.action.skip" = "ข้าม"; + +"walkthrough.page.1.title" = "รับรองอุปกรณ์ 10 เครื่องในคราวเดียว"; +"walkthrough.page.1.description" = "ปกป้องตัวคุณบนอุปกรณ์ถึง 10 เครื่องในเวลาเดียวกัน"; +"walkthrough.page.2.title" = "เชื่อมต่อไปยังภูมิภาคใดก็ตามได้อย่างง่ายดาย"; +"walkthrough.page.2.description" = "ด้วยเซิร์ฟเวอร์ที่มีอยู่ทั่วโลก คุณจะได้รับความคุ้มครองตลอดเวลา"; +"walkthrough.page.3.title" = "ปกป้องตัวคุณจากโฆษณา"; +"walkthrough.page.3.description" = "การเปิดใช้งานตัวปิดกั้นเนื้อหาของเราจะเป็นการป้องกันไม่ให้แสดงโฆษณาใน Safari"; + +"share.data.buttons.accept" = "ยอมรับ"; +"share.data.buttons.noThanks" = "ไม่ล่ะ ขอบคุณ"; +"share.data.buttons.readMore" = "อ่านเพิ่มเติม"; +"share.data.text.title" = "โปรดช่วยเราปรับปรุงบริการของเรา"; +"share.data.text.description" = "เพื่อช่วยให้เรามั่นใจในประสิทธิภาพการเชื่อมต่อของบริการของเรา คุณสามารถแชร์สถิติการเชื่อมต่อของคุณกับเราโดยไม่ระบุชื่อ รายงานเหล่านี้ไม่รวมข้อมูลส่วนบุคคลที่สามารถระบุตัวตนได้"; +"share.data.text.footer" = "คุณสามารถควบคุมสิ่งนี้ได้จากการตั้งค่าของคุณ"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/UI.strings new file mode 100644 index 000000000..3069ecff4 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "เวอร์ชั่น %@ (%@)"; +"global.close" = "ปิด"; +"global.ok" = "ตกลง"; +"global.cancel" = "ยกเลิก"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings new file mode 100644 index 000000000..637de14e0 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "ลงชื่อเข้าใช้บัญชีของคุณ"; +"login.username.placeholder" = "ชื่อผู้ใช้ (p1234567)"; +"login.password.placeholder" = "รหัสผ่าน"; +"login.submit" = "เข้าสู่ระบบ"; +"login.restore.button" = "ยังไม่ได้รับรายละเอียดบัญชีหรือ"; +"login.error.title" = "เข้าสู่ระบบ"; +"login.error.validation" = "คุณต้องกรอกชื่อผู้ใช้และรหัสผ่าน"; +"login.error.unauthorized" = "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "เข้าสู่ระบบโดยใช้ใบเสร็จรับเงิน"; +"login.magic.link.title" = "เข้าสู่ระบบโดยใช้ลิงก์อีเมลวิเศษ"; +"login.magic.link.response" = "โปรดตรวจสอบอีเมลของคุณเพื่อดูลิงค์สำหรับเข้าสู่ระบบ"; +"login.magic.link.send" = "ส่งลิงก์"; +"login.magic.link.invalid.email" = "อีเมลไม่ถูกต้อง กรุณาลองอีกครั้ง"; + +"purchase.title" = "เลือกแผน VPN"; +"purchase.subtitle" = "รับประกันการคืนเงินภายใน 30 วัน"; +"purchase.email.placeholder" = "อีเมลแอดเดรส"; +"purchase.continue" = "ดำเนินการต่อ"; +"purchase.login.footer" = "มีบัญชีแล้วหรือยัง"; +"purchase.login.button" = "ลงชื่อเข้าใช้"; +"purchase.error.title" = "ซื้อ"; +"purchase.error.validation" = "คุณต้องใส่ที่อยู่อีเมล"; +"purchase.error.connectivity.title" = "ความล้มเหลวในการเชื่อมต่อ"; +"purchase.error.connectivity.description" = "เราไม่สามารถเข้าถึง Private Internet Access ซึ่งอาจเป็นเพราะอินเทอร์เน็ตไม่เสถียรหรือบริการของเราถูกบล็อกในประเทศของคุณ"; +"purchase.confirm.form.email" = "กรุณากรอกอีเมลของคุณ"; +"purchase.confirm.plan" = "คุณกำลังซื้อแผน %@"; +"purchase.email.why" = "โปรดแจ้งอีเมลสำหรับส่งชื่อผู้ใช้และรหัสผ่านของคุณ"; +"purchase.submit" = "ส่ง"; +"purchase.or" = "หรือ"; + +"upgrade.header" = "ยินดีต้อนรับกลับมา!"; +"upgrade.title" = "หากต้องการใช้ Private Internet Access คุณจะต้องต่ออายุสมาชิกของคุณ"; +"upgrade.renew.now" = "ต่ออายุตอนนี้"; + + + +"redeem.title" = "ใช้สิทธิ์บัตรของขวัญ"; +"redeem.subtitle" = "พิมพ์ที่อยู่อีเมลของคุณและ PIN %lu หลักจากบัตรของขวัญหรือบัตรทดลองด้านล่าง"; +"redeem.email.placeholder" = "ที่อยู่อีเมล"; +"redeem.submit" = "ส่ง"; +"redeem.error.title" = "ใช้สิทธิ์"; +"redeem.error.code" = "รหัสต้องประกอบด้วยตัวเลข %lu หลัก"; +"redeem.error.allfields" = "กรุณากรอกอีเมลและ PIN"; +"redeem.accessibility.back" = "กลับ"; +"redeem.giftcard.placeholder" = "PIN บัตรของขวัญ"; + +"plan.monthly.title" = "รายเดือน"; +"plan.yearly.title" = "รายปี"; +"plan.yearly.detail_format" = "%@%@ ต่อปี"; +"plan.price_format" = "%@/เดือน"; +"plan.best_value" = "คุ้มค่าที่สุด"; +"plan.accessibility.per_month" = "ต่อเดือน"; + +"restore.title" = "คืนค่าการซื้อยังไม่ได้คิดเครดิต"; +"restore.subtitle" = "หากคุณทำการซื้อแผนผ่านแอพนี้และยังไม่ได้รับข้อมูลประจำตัว คุณสามารถส่งอีกครั้งได้จากที่นี่ คุณจะไม่ถูกเรียกเก็บเงินซ้ำอีกครั้งในกระบวนการนี้"; +"restore.email.placeholder" = "อีเมลแอดเดรส"; +"restore.submit" = "ยืนยัน"; + +"iap.error.message.unavailable" = "ไม่พบเซิร์ฟเวอร์แอปเปิ้ลในขณะนี้ โปรดลองใหม่ภายหลัง"; +"iap.error.title" = "ข้อผิดพลาด"; + +"agreement.trials.title" = "ข้อกำหนดและเงื่อนไขการทดลองใช้ฟรี"; +"agreement.trials.message" = "ยอดชำระเงินจะถูกหักจากบัญชี Apple ID ของคุณเมื่อมีการยืนยันคำสั่งซื้อ ระบบจะต่ออายุสมาชิกโดยอัตโนมัติเว้นแต่จะมีการยกเลิกล่วงหน้าอย่างน้อย 24 ชั่วโมงก่อนที่จะสิ้นสุดรอบใช้งานปัจจุบัน บัญชีของคุณจะถูกเรียกเก็บเงินค่าต่ออายุสมาชิกภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบใช้งานปัจจุบัน คุณสามารถจัดการและยกเลิกการเป็นสมาชิกได้โดยไปที่การตั้งค่าบัญชีใน App Store หลังจากซื้อแล้ว\n\nบางระบบสมาชิกแบบชำระเงินอาจเสนอให้คุณทดลองใช้ฟรีก่อนที่จะเรียกเก็บเงินผ่านช่องทางการชำระเงินที่คุณเลือกไว้ หากคุณตัดสินใจที่จะยกเลิกการสมัครสมาชิกแบบชำระเงินก่อนที่เราจะเริ่มเรียกเก็บเงินผ่านช่องทางการชำระเงินที่เลือกไว้ ให้ทำการยกเลิกสมาชิกล่วงหน้าอย่างน้อย 24 ชั่วโมงก่อนที่ช่วงทดลองใช้ฟรีจะสิ้นสุดลง\n\nสามารถทดลองใช้ฟรีเฉพาะผู้ใช้ใหม่เท่านั้นและขึ้นอยู่กับดุลยพินิจของเราแต่เพียงผู้เดียว และหากคุณพยายามที่จะสมัครเพื่อทดลองใช้ฟรีซ้ำอีก คุณจะถูกเรียกเก็บค่าธรรมเนียมการสมัครสมาชิกตามมาตรฐานทันที\n\nเราขอสงวนสิทธิ์ในการเพิกถอนสิทธิ์ทดลองใช้ฟรีของคุณได้ตลอดเวลา\n\nส่วนที่ไม่ได้ใช้งานของช่วงทดลองใช้ฟรีจะถูกหักทิ้งเมื่อมีการสมัครสมาชิก\n\nการสมัครสมาชิกถือว่าเป็นการยอมรับข้อกำหนดและเงื่อนไขนี้"; +"agreement.message" = "หลังจากทดลองใช้ฟรี 7 วัน ระบบจะต่ออายุสมาชิกนี้โดยอัตโนมัติในราคา %@ เว้นแต่จะมีการยกเลิกล่วงหน้าอย่างน้อย 24 ชั่วโมงก่อนที่จะสิ้นสุดรอบใช้งานปัจจุบัน บัญชี Apple ID ของคุณจะถูกเรียกเก็บเงินค่าต่ออายุสมาชิกภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบใช้งานปัจจุบัน คุณสามารถจัดการและยกเลิกการเป็นสมาชิกได้โดยไปที่การตั้งค่าบัญชีใน App Store หลังจากซื้อแล้ว จำกัดสิทธิ์การทดลองใช้ฟรี 7 วัน เพียง 1 สิทธิ์ต่อผู้ใช้หนึ่งราย ส่วนที่ไม่ได้ใช้งานของช่วงทดลองใช้ฟรีหากมีให้จะถูกริบเมื่อผู้ใช้ซื้อการสมัครสมาชิก ราคาทั้งหมดรวมภาษีการขายในท้องที่\n\nการลงทะเบียนจะถือว่าคุณยินยอมตาม $1 และ $2"; +"agreement.trials.yearly.plan" = "ปี"; +"agreement.trials.monthly.plan" = "เดือน"; + +"agreement.message.tos" = "ข้อตกลงการใช้บริการ"; +"agreement.message.privacy" = "นโยบายความเป็นส่วนตัว"; + +"getstarted.buttons.buyaccount" = "ซื้อบัญชี"; + +"gdpr.collect.data.title" = "ข้อมูลส่วนบุคคลที่เรารวบรวม"; +"gdpr.collect.data.description" = "อีเมลเพื่อจุดประสงค์ในการจัดการและการป้องกันบัญชีจากการใช้งานในทางที่ผิด"; +"gdpr.usage.data.title" = "การใช้ข้อมูลส่วนบุคคลที่เรารวบรวม"; +"gdpr.usage.data.description" = "ที่อยู่อีเมลใช้ในการส่งข้อมูลการสมัครสมาชิก การยืนยันการชำระเงิน การติดต่อกับลูกค้า และข้อเสนอส่งเสริมการขาย Private Internet Access เท่านั้น"; +"gdpr.accept.button.title" = "ยอมรับและดำเนินการต่อ"; + +"update.account.email.error" = "ไม่สามารถแก้ไขอีเมลบัญชีได้"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings new file mode 100644 index 000000000..36d6ad53a --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings @@ -0,0 +1,166 @@ +/* (No Comment) */ +"failure.message" = "Şu anda hesap oluşturamıyoruz.\nLütfen daha sonra tekrar deneyin.\n\nUygulama yeniden açıldığından hesap oluşturma tekrar denenecektir."; + +/* (No Comment) */ +"failure.purchase.sandbox.message" = "Seçilen Sandbox aboneliği üretim ortamında mevcut değil."; + +/* (No Comment) */ +"failure.redeem.claimed.message" = "Bu kart önceden başka bir hesap tarafından talep edilmiş. Farklı bir PIN girmeyi deneyebilirsiniz."; + +/* (No Comment) */ +"failure.redeem.claimed.title" = "Kart önceden talep edilmiş"; + +/* (No Comment) */ +"failure.redeem.invalid.message" = "Görünüşe bakılırsa geçersiz bir kart PIN'i girdiniz. Lütfen tekrar deneyin."; + +/* (No Comment) */ +"failure.redeem.invalid.title" = "Geçersiz kart PIN'i"; + +/* (No Comment) */ +"failure.submit" = "GERİ DÖN"; + +/* (No Comment) */ +"failure.title" = "Hesap Oluşturma Hatası"; + +/* (No Comment) */ +"failure.vc_title" = "Kaydolma başarısız oldu"; + +/* (No Comment) */ +"in_progress.message" = "Sistemimizle satın alım işleminizi onaylıyoruz. Biraz zaman alabilir; lütfen bekleyin."; + +/* (No Comment) */ +"in_progress.redeem.message" = "Kart PIN'inizi sistemimizde onaylıyoruz. Bu biraz zaman alabilir, lütfen bekleyin."; + +/* Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. */ +"in_progress.title" = "Kaydolmayı onayla"; + +/* (No Comment) */ +"purchase.subscribe.now" = "Hemen abone ol"; + +/* (No Comment) */ +"purchase.trials.1year.protection" = "1 yıllık gizlilik ve kimlik koruması"; + +/* (No Comment) */ +"purchase.trials.all.plans" = "Tüm mevcut planlara bakın"; + +/* (No Comment) */ +"purchase.trials.anonymous" = "IP'nizi gizleyerek İnternet'te isimsiz gezinin."; + +/* (No Comment) */ +"purchase.trials.devices" = "Aynı anda 10 cihaz desteği"; + +/* (No Comment) */ +"purchase.trials.devices.description" = "Aynı anda 10 cihazda kendinizi koruyun."; + +/* (No Comment) */ +"purchase.trials.intro" = "7 günlük ücretsiz deneme sürenizi başlatın"; + +/* (No Comment) */ +"purchase.trials.money.back" = "30 günlük para iade garantisi"; + +/* (No Comment) */ +"purchase.trials.price.after" = "Ardından %@"; + +/* (No Comment) */ +"purchase.trials.region" = "Tüm bölgelere kolayca bağlanın"; + +/* (No Comment) */ +"purchase.trials.servers" = "32 ülkede en az 3.300 sunucu"; + +/* (No Comment) */ +"purchase.trials.start" = "Aboneliği başlat"; + +/* (No Comment) */ +"purchase.uncredited.alert.button.cancel" = "İptal"; + +/* (No Comment) */ +"purchase.uncredited.alert.button.recover" = "Hesabı kurtar"; + +/* (No Comment) */ +"purchase.uncredited.alert.message" = "Hesaba yansıtılmamış olan işlemleriniz var. Hesap bilgilerinizi kurtarmak ister misiniz?"; + +/* (No Comment) */ +"share.data.buttons.accept" = "Kabul Et"; + +/* (No Comment) */ +"share.data.buttons.noThanks" = "Hayır, teşekkürler"; + +/* (No Comment) */ +"share.data.buttons.readMore" = "Devamını oku"; + +/* (No Comment) */ +"share.data.readMore.text.description" = "Bu asgari bilgi, potansiyel bağlantı sorunlarını tanımlayıp düzeltmemize yardımcı olur. Bu bilgiyi paylaşmak için onay verilmesi ve varsayılan olarak kapalı olduğu için elle etkinleştirilmesi gerektiğini dikkate alın.\n\nŞu olaylarla ilgili bilgi toplayacağız:\n\n - Bağlantı Denemesi\n - Bağlantı İptal Edildi\n - Bağlantı Kuruldu\n\nTüm bu olaylar için şu bilgileri toplayacağız:\n - Platform\n - Uygulama sürümü\n - Uygulama türü (ön sürüm olup olmadığı)\n - Kullanılan protokol\n - Bağlantı kaynağı (manuel ya da otomasyon ile)\n\nTüm olaylarda rastgele oluşturulan eşsiz bir kimlik yer alacak. Bu kimlik kullanıcı hesabınızla bağlantılı değildir. Bu eşsiz kimlik, gizliliğin korunması açısından günlük olarak üretilir.\n\nKontrol daima sizde olacak. Ayarlardan hangi verileri topladığımızı görebilir ve bunu istediğiniz zaman kapatabilirsiniz."; + +/* (No Comment) */ +"share.data.text.description" = "Hizmetimizin bağlantı performansını korumamıza yardımcı olmak için bağlantı istatistiklerinizi isimsiz olarak bizimle paylaşabilirsiniz. Bu raporlarda kişiyi tanımlayabilecek herhangi bir bilgi yer almaz."; + +/* (No Comment) */ +"share.data.text.footer" = "Bunu istediğiniz zaman ayarlarınızdan kontrol edebilirsiniz"; + +/* (No Comment) */ +"share.data.text.title" = "Lütfen hizmetimizi geliştirmemize yardım edin"; + +/* (No Comment) */ +"success.message_format" = "Bize kayıt olduğunuz için teşekkürler. Hesap kullanıcı adı ve parolanızı %@ e-posta adresinize gönderdik"; + +/* (No Comment) */ +"success.password.caption" = "Şifre"; + +/* (No Comment) */ +"success.redeem.message" = "Kısa süre içinde kullanıcı adınızı ve şifrenizi içeren bir e-posta alacaksınız.\n\nGiriş bilgileriniz"; + +/* (No Comment) */ +"success.redeem.title" = "Kart başarıyla kullanıldı"; + +/* (No Comment) */ +"success.submit" = "Başlarken"; + +/* (No Comment) */ +"success.title" = "Satın Alma Tamamlandı"; + +/* (No Comment) */ +"success.username.caption" = "Kullanıcı Adı"; + +/* (No Comment) */ +"unreachable.message" = "İnternet bağlantısı yok. Lütfen İnternet bağlantınız olup olmadığını kontrol edin ve tekrar aşağıya tıklamayı deneyin.\n\nİşlemi bitirmek için uygulamaya daha sonra tekrar gelebilirsiniz."; + +/* (No Comment) */ +"unreachable.submit" = "TEKRAR DENE"; + +/* (No Comment) */ +"unreachable.title" = "Heeey!"; + +/* (No Comment) */ +"unreachable.vc_title" = "Hata"; + +/* (No Comment) */ +"walkthrough.action.done" = "BİTTİ"; + +/* WALKTHROUGH */ +"walkthrough.action.next" = "İLERİ"; + +/* (No Comment) */ +"walkthrough.action.skip" = "ATLA"; + +/* (No Comment) */ +"walkthrough.page.1.description" = "Aynı anda 10 cihazda koruma sağlayın."; + +/* (No Comment) */ +"walkthrough.page.1.title" = "Aynı anda 10 cihazı destekler"; + +/* (No Comment) */ +"walkthrough.page.2.description" = "Dünya çapındaki sunucularla daima koruma altındasınız."; + +/* (No Comment) */ +"walkthrough.page.2.title" = "Herhangi bir bölgeye kolayca bağlanın"; + +/* (No Comment) */ +"walkthrough.page.3.description" = "İçerik Engelleyicimizi etkinleştirdiğinizde Safari'de reklamların gösterilmesi engellenir."; + +/* (No Comment) */ +"walkthrough.page.3.title" = "Kendinizi reklamlardan koruyun"; + diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings new file mode 100644 index 000000000..fc6795eb9 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings @@ -0,0 +1,12 @@ +/* (No Comment) */ +"global.cancel" = "İptal"; + +/* (No Comment) */ +"global.close" = "Kapat"; + +/* (No Comment) */ +"global.ok" = "Tamam"; + +/* (No Comment) */ +"global.version.format" = "Sürüm %@ (%@)"; + diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings new file mode 100644 index 000000000..49d7ab5ca --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings @@ -0,0 +1,205 @@ +/* (No Comment) */ +"agreement.message" = "Bu abonelik, deneme süresinin sonuna en az 24 saat kalana dek iptal edilmezse, otomatik olarak %@ karşılığında yenilenir. Deneme süresinin sonuna 24 saat kaldıktan sonra, Apple Kimliğinizin hesabından yenileme ücreti alınır. Satın alım işleminden sonra App Store hesap ayarlarına giderek abonelik ayarlarınızı değiştirebilir ve aboneliklerinizi iptal edebilirsiniz. 7 günlük deneme süresi, her kullanıcı için bir tane 7 günlük deneme süresi hakkı ile sınırlıdır. Kullanıcı bir abonelik satın aldığında, teklif edilmişse, ücretsiz deneme süresinin kullanılmayan herhangi bir kısmı geçerliliğini yitirir. Tüm fiyatlara uygulanabilir yerel satış vergileri dahildir.\n\nKaydolduğunuzda, $1 ile $2 unsurlarını kabul etmiş olursunuz."; + +/* (No Comment) */ +"agreement.message.privacy" = "Gizlilik Politikası"; + +/* (No Comment) */ +"agreement.message.tos" = "Hizmet Koşulları"; + +/* (No Comment) */ +"agreement.trials.message" = "Satın alım onaylandıktan sonra, ödeme ücreti, Apple Kimliği hesabınızdan alınır. Mevcut dönemin sonuna en az 24 saat kalana dek iptal edilmezse, abonelik otomatik olarak yenilenir. Mevcut dönemin sonuna 24 saat kaldıktan sonra hesabınızdan yenileme ücreti alınır. Satın alım işleminden sonra App Store'daki hesap ayarlarınıza giderek abonelik ayarlarınızı değiştirebilir ve aboneliğinizi iptal edebilirsiniz.\n\nBelirli Ücretli Abonelik planlarında, seçtiğiniz ödeme yöntemiyle ücret alınmadan önce, bir ücretsiz kullanım süresi sunulabilir. Seçtiğiniz ödeme yöntemiyle sizden ücret almaya başlamamızdan önce Ücretli Aboneliğinizi iptal etmek isterseniz, ücretsiz kullanım süresinin sonuna en az 24 saat kalana dek aboneliğinizi iptal etmelisiniz.\n\nÜcretsiz deneme süresinden sadece yeni kullanıcılar faydalanabilir ve bu tamamen bizim takdirimizdedir. Tekrar kaydolarak bir ücretsiz deneme süresi daha almaya çalışırsanız, standart Abonelik Ücreti anında hesabınızdan düşülür.\n\nÜcretsiz deneme sürenizi istediğimiz zaman iptal etme hakkına sahibiz.\n\nBir abonelik satın aldığınızda, ücretsiz kullanım sürenizin kullanılmayan kısmını yitirirsiniz.\n\nKaydolduğunuzda bu şart ve koşulları kabul etmiş olursunuz."; + +/* (No Comment) */ +"agreement.trials.monthly.plan" = "ay"; + +/* (No Comment) */ +"agreement.trials.title" = "Ücretsiz deneme süresi şart ve koşulları"; + +/* (No Comment) */ +"agreement.trials.yearly.plan" = "yıl"; + +/* (No Comment) */ +"gdpr.accept.button.title" = "Kabul edip devam et"; + +/* (No Comment) */ +"gdpr.collect.data.description" = "Hesap yönetimi ve ihlalden koruma için E-posta Adresi."; + +/* (No Comment) */ +"gdpr.collect.data.title" = "Topladığımız kişisel bilgiler"; + +/* (No Comment) */ +"gdpr.usage.data.description" = "E-posta adresi sadece abonelik bilgilerinin, ödeme onaylarının, müşteri iletişim unsurlarının ve Private Internet Access'in promosyonel tekliflerinin gönderilmesi için kullanılır."; + +/* (No Comment) */ +"gdpr.usage.data.title" = "Tarafımızca toplanan kişisel bilgilerin kullanım şekilleri"; + +/* (No Comment) */ +"getstarted.buttons.buyaccount" = "Hesap satın al"; + +/* (No Comment) */ +"iap.error.message.unavailable" = "Apple sunucuları şu anda kullanılamıyor. Lütfen daha sonra tekrar deneyin."; + +/* (No Comment) */ +"iap.error.title" = "Hata"; + +/* (No Comment) */ +"login.error.throttled" = "Bu kullanıcı adı ile çok fazla kez yanlış giriş yapıldı. Lütfen daha sonra tekrar deneyin."; + +/* (No Comment) */ +"login.error.title" = "Giriş yap"; + +/* (No Comment) */ +"login.error.unauthorized" = "Kullanıcı adınız ya da şifreniz hatalı."; + +/* (No Comment) */ +"login.error.validation" = "Bir kullanıcı adı ve şifre girmelisiniz."; + +/* (No Comment) */ +"login.magic.link.invalid.email" = "E-posta adresi geçersiz. Lütfen tekrar deneyin."; + +/* (No Comment) */ +"login.magic.link.response" = "Giriş linkini bulmak için lütfen e-postalarınıza bakın."; + +/* (No Comment) */ +"login.magic.link.send" = "Link Gönder"; + +/* (No Comment) */ +"login.magic.link.title" = "Sihirli e-posta linki ile giriş yap"; + +/* (No Comment) */ +"login.password.placeholder" = "Şifre"; + +/* (No Comment) */ +"login.receipt.button" = "Satın alım faturasıyla giriş yapın"; + +/* (No Comment) */ +"login.restore.button" = "Hesap bilgilerinizi almadınız mı?"; + +/* (No Comment) */ +"login.submit" = "GİRİŞ YAP"; + +/* Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. */ +"login.title" = "Hesabınıza giriş yapın"; + +/* (No Comment) */ +"login.username.placeholder" = "Kullanıcı Adı (p1234567)"; + +/* (No Comment) */ +"plan.accessibility.per_month" = "aylık"; + +/* (No Comment) */ +"plan.best_value" = "En iyi fiyat"; + +/* (No Comment) */ +"plan.monthly.title" = "Aylık"; + +/* (No Comment) */ +"plan.price_format" = "%@/ay"; + +/* (No Comment) */ +"plan.yearly.detail_format" = "Yılda %@%@"; + +/* (No Comment) */ +"plan.yearly.title" = "Yıllık"; + +/* (No Comment) */ +"purchase.confirm.form.email" = "E-posta adresinizi girin"; + +/* (No Comment) */ +"purchase.confirm.plan" = "%@ planını satın alıyorsunuz"; + +/* (No Comment) */ +"purchase.continue" = "Devam et"; + +/* (No Comment) */ +"purchase.email.placeholder" = "E-posta adresi"; + +/* (No Comment) */ +"purchase.email.why" = "Kullanıcı adınızla şifrenizi gönderebilmemiz için e-posta adresinize ihtiyacımız var."; + +/* (No Comment) */ +"purchase.error.connectivity.description" = "Özel İnternet Erişimi'ne ulaşamıyoruz. Bu zayıf internet yüzünden olabilir veya hizmetimiz ülkenizde engelleniyor."; + +/* (No Comment) */ +"purchase.error.connectivity.title" = "Bağlantı Hatası"; + +/* (No Comment) */ +"purchase.error.title" = "Satın Al"; + +/* (No Comment) */ +"purchase.error.validation" = "Bir e-posta adresi girmeniz gerekiyor."; + +/* (No Comment) */ +"purchase.login.button" = "Giriş yapın"; + +/* (No Comment) */ +"purchase.login.footer" = "Hesabınız var mı?"; + +/* (No Comment) */ +"purchase.or" = "veya"; + +/* (No Comment) */ +"purchase.submit" = "Gönder"; + +/* (No Comment) */ +"purchase.subtitle" = "30 günlük para iade garantisi"; + +/* (No Comment) */ +"purchase.title" = "Bir VPN planı seçin"; + +/* (No Comment) */ +"redeem.accessibility.back" = "Geri"; + +/* (No Comment) */ +"redeem.email.placeholder" = "E-posta adresi"; + +/* (No Comment) */ +"redeem.error.allfields" = "Lütfen e-posta adresinizi ve kart PIN numaranızı girin."; + +/* (No Comment) */ +"redeem.error.code" = "Kod, %lu sayısal haneden oluşmalıdır."; + +/* (No Comment) */ +"redeem.error.title" = "Kullan"; + +/* (No Comment) */ +"redeem.giftcard.placeholder" = "Hediye kartı ve PIN"; + +/* (No Comment) */ +"redeem.submit" = "Gönder"; + +/* (No Comment) */ +"redeem.subtitle" = "E-posta adresinizi ve hediye kartınızdaki ya da deneme kartınızdaki %lu haneli PIN'i aşağıya girin."; + +/* (No Comment) */ +"redeem.title" = "Hediye kartını kullan"; + +/* (No Comment) */ +"restore.email.placeholder" = "E-posta adresi"; + +/* (No Comment) */ +"restore.submit" = "ONAYLA"; + +/* (No Comment) */ +"restore.subtitle" = "Bu uygulamadan bir plan satın aldıktan sonra hesap bilgilerinizi alamadıysanız, onları buradan tekrar gönderebilirsiniz. Bu işlem esnasında sizden ücret alınmayacak."; + +/* (No Comment) */ +"restore.title" = "Bilgileri gönderilmeyen satın alma işlemini tekrarlayın"; + +/* (No Comment) */ +"update.account.email.error" = "Hesap e-posta adresi değiştirilemedi"; + +/* (No Comment) */ +"upgrade.header" = "Tekrar Hoş Geldiniz!"; + +/* (No Comment) */ +"upgrade.renew.now" = "Hemen yenileyin"; + +/* (No Comment) */ +"upgrade.title" = "Private Internet Access kullanabilmek için aboneliğinizi yenilemeniz gerekiyor."; + diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings new file mode 100644 index 000000000..2f4afbb78 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "确认注册"; +"in_progress.message" = "我们正在确认您在我们系统中的购买。这可能需要一点时间,请耐心等待。"; +"in_progress.redeem.message" = "我们正在通过系统确认您的卡片PIN。这可能需要一些时间,请耐心等待。"; + +"success.title" = "购买完成"; +"success.message_format" = "感谢注册。我们已将您的用户名和密码发送至您的电子邮箱:%@"; +"success.redeem.title" = "卡片兑换成功"; +"success.redeem.message" = "您将很快收到一封电子邮件,记有您的用户名和密码。\n\n您的登录详情"; +"success.username.caption" = "用户名"; +"success.password.caption" = "密码"; +"success.submit" = "开始体验"; + +"failure.vc_title" = "注册失败"; +"failure.title" = "账户创建失败"; +"failure.message" = "我们现在无法创建账号。\n请稍后再试。\n\n重新打开本应用将会再次尝试创建账号。"; +"failure.purchase.sandbox.message" = "所选的沙盒订阅不适用于生产"; +"failure.redeem.invalid.title" = "卡片PIN无效"; +"failure.redeem.invalid.message" = "您输入的卡片PIN似乎无效。请重试。"; +"failure.redeem.claimed.title" = "卡片已使用"; +"failure.redeem.claimed.message" = "此卡片似乎已被另一个账号使用。您可尝试输入另一个PIN。"; +"failure.submit" = "返回"; + +"unreachable.vc_title" = "错误"; +"unreachable.title" = "糟糕!"; +"unreachable.message" = "未找到网络连接。请确认您已接入网络,然后点击下面的重试。\n\n您可在稍后再回到本应用完成该操作。"; +"unreachable.submit" = "重试"; + +"purchase.uncredited.alert.message" = "你有未入账的的交易。要恢复您的账户详情吗?"; +"purchase.uncredited.alert.button.cancel" = "取消"; +"purchase.uncredited.alert.button.recover" = "恢复账户"; + +"purchase.trials.intro" = "开始 7 天免费试用"; +"purchase.trials.price.after" = "然后 %@"; +"purchase.trials.money.back" = "7 天退款保证"; +"purchase.trials.1year.protection" = "1 年隐私和身份保护"; +"purchase.trials.anonymous" = "匿名浏览并隐藏您的 IP。"; +"purchase.trials.devices" = "一次支持 10 台设备"; +"purchase.trials.devices.description" = "一次在多达 10 台设备上保护自己。"; +"purchase.trials.region" = "轻松连接到任何地区"; +"purchase.trials.servers" = "在 32 个国家h地区拥有超过 3300 台服务器"; +"purchase.trials.start" = "开始订阅"; +"purchase.trials.all.plans" = "查看所有可用套餐"; + +"purchase.subscribe.now" = "立即订阅"; + +// WALKTHROUGH + +"walkthrough.action.next" = "下一个"; +"walkthrough.action.done" = "完成"; +"walkthrough.action.skip" = "跳过"; + +"walkthrough.page.1.title" = "一次支持 10 台设备"; +"walkthrough.page.1.description" = "一次在多达 10 台设备上保护自己。"; +"walkthrough.page.2.title" = "轻松连接到任何地区"; +"walkthrough.page.2.description" = "服务器遍布世界各地,您始终受到保护。"; +"walkthrough.page.3.title" = "让自己远离广告"; +"walkthrough.page.3.description" = "启用内容拦截器以防止 Safari 中出现广告。"; + +"share.data.buttons.accept" = "接受"; +"share.data.buttons.noThanks" = "不用,谢谢"; +"share.data.buttons.readMore" = "阅读更多"; +"share.data.text.title" = "请帮助我们改进服务"; +"share.data.text.description" = "为了帮助我们保持服务的连接性能,您可以匿名与我们共享您的连接统计数据。这些报告不包括任何可识别个人身份的信息。"; +"share.data.text.footer" = "您始终可以从设置中进行控制"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings new file mode 100644 index 000000000..e6f012399 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "版本 %@ (%@)"; +"global.close" = "关闭"; +"global.ok" = "确定"; +"global.cancel" = "取消"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings new file mode 100644 index 000000000..8d5c7e113 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "登录到您的帐户"; +"login.username.placeholder" = "用户名 (p1234567)"; +"login.password.placeholder" = "密码"; +"login.submit" = "登录"; +"login.restore.button" = "没有收到账户详情?"; +"login.error.title" = "登录"; +"login.error.validation" = "您必须输入用户名和密码。"; +"login.error.unauthorized" = "您的用户名或密码不正确。"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "使用购买收据登录"; +"login.magic.link.title" = "使用魔法电子邮件链接登录"; +"login.magic.link.response" = "请检查您的电子邮件,以查找登录链接。"; +"login.magic.link.send" = "发送链接"; +"login.magic.link.invalid.email" = "电子邮箱乎无效。请重试。"; + +"purchase.title" = "选择 VPN 套餐"; +"purchase.subtitle" = "7 天退款保证"; +"purchase.email.placeholder" = "电子邮件地址"; +"purchase.continue" = "继续"; +"purchase.login.footer" = "已有帐号?"; +"purchase.login.button" = "登录"; +"purchase.error.title" = "购买"; +"purchase.error.validation" = "您必须输入一个电子邮箱地址。"; +"purchase.error.connectivity.title" = "连接失败"; +"purchase.error.connectivity.description" = "我们无法接入Private Internet Access。原因可能是互联网连接不良或者我们的服务在您的国家遭到屏蔽。"; +"purchase.confirm.form.email" = "请输入您的电子邮件地址"; +"purchase.confirm.plan" = "您正在购买 %@ 套餐"; +"purchase.email.why" = "我们需要您的电子邮件以发送您的用户名和密码。"; +"purchase.submit" = "提交"; +"purchase.or" = "或"; + +"upgrade.header" = "欢迎回来!"; +"upgrade.title" = "您需要续订才能使用 Private Internet Access。"; +"upgrade.renew.now" = "立即续订"; + + + +"redeem.title" = "兑换礼品卡"; +"redeem.subtitle" = "请输入您的电子邮箱地址以及礼品卡或试用卡上的%lu位数字PIN。"; +"redeem.email.placeholder" = "邮箱地址"; +"redeem.submit" = "提交"; +"redeem.error.title" = "兑换"; +"redeem.error.code" = "PIN码必须包含%lu个数字。"; +"redeem.error.allfields" = "请输入您的电子邮件和卡片 PIN 码。"; +"redeem.accessibility.back" = "返回"; +"redeem.giftcard.placeholder" = "礼品卡 PIN"; + +"plan.monthly.title" = "每月"; +"plan.yearly.title" = "每年"; +"plan.yearly.detail_format" = "%@%@/每年"; +"plan.price_format" = "%@/每月"; +"plan.best_value" = "最超值"; +"plan.accessibility.per_month" = "每月"; + +"restore.title" = "恢复未入账的购买"; +"restore.subtitle" = "如果您通过此 app 购买了套餐,但没有收到凭据,可以从这里重新发送。在此过程中您不会被收费。"; +"restore.email.placeholder" = "电子邮件地址"; +"restore.submit" = "确认"; + +"iap.error.message.unavailable" = "Apple 服务器目前不可用。请稍后重试。"; +"iap.error.title" = "错误"; + +"agreement.trials.title" = "免费试用条款和条件"; +"agreement.trials.message" = "确认购买后,将从您的 Apple ID 账户中收取款项。除非在当前使用期结束前至少提前 24 小时取消,否则会自动续订。您的账户将在当前使用期结束前 24 小时内收取续订费用。您可以在购买后前往 App Store 上的账户设置来管理和取消订阅。\n\n某些“付费订阅”可能会在向您收取款项之前先提供免费试用。如果您在我们开始收取款项之前决定取消订阅“付费订阅”,请在免费试用结束前至少提前 24 小时取消订阅。\n\n免费试用仅适用于新用户,并由我们自行决定,如果您尝试注册额外的免费试用,您将被立即收取标准订阅费。\n\n我们有权随时撤销您的免费试用。\n\n免费试用期的任何未使用部分将在购买订阅时取消。\n\n注册即表示接受上述条款和条件。"; +"agreement.message" = "免费试用 7 天后,除非在试用期结束前至少提前 24 小时取消,否则此订阅将自动续订 %@。您的 Apple ID 账户将在试用期结束前 24 小时内收取续订费用。您可以在购买后前往 App Store 上的账户设置来管理和取消订阅。每个用户仅可享受一次 7 天试用优惠。免费试用期的任何未使用部分(如果提供)将在用户购买订阅时失效。所有价格均包含适用的当地营业税。\n\n注册即表示接受$1和$2。"; +"agreement.trials.yearly.plan" = "年"; +"agreement.trials.monthly.plan" = "月"; + +"agreement.message.tos" = "服务条款"; +"agreement.message.privacy" = "隐私政策"; + +"getstarted.buttons.buyaccount" = "购买账户"; + +"gdpr.collect.data.title" = "我们收集的个人信息"; +"gdpr.collect.data.description" = "用于账户管理和防止滥用的电子邮件地址。"; +"gdpr.usage.data.title" = "我们收集的个人信息的使用方式"; +"gdpr.usage.data.description" = "电子邮件地址仅用于发送订阅信息、付款确认、客户通信以及 Private Internet Access 促销优惠。"; +"gdpr.accept.button.title" = "同意并继续"; + +"update.account.email.error" = "无法修改账户电子邮件"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings new file mode 100644 index 000000000..ed78c07e6 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "壓認註冊"; +"in_progress.message" = "我們的系統正確認您的購買交易,可能需要停留在此畫面幾分鐘時間。"; +"in_progress.redeem.message" = "我們的系統正在確認您的卡 PIN 碼。這可能需要一點時間,請稍候。"; + +"success.title" = "購買完成"; +"success.message_format" = "感謝您註冊我們的服務!我們已將您的帳戶使用者名稱和密碼寄送到您的電子郵件地址:%@"; +"success.redeem.title" = "已成功兌換禮品卡"; +"success.redeem.message" = "您很快就會收到一封電子郵件,內有使用者名稱及密碼。\n\n您的登入資料"; +"success.username.caption" = "使用者名稱"; +"success.password.caption" = "密碼"; +"success.submit" = "開始使用"; + +"failure.vc_title" = "註冊失敗"; +"failure.title" = "帳戶建立失敗"; +"failure.message" = "我們目前未能建立帳戶,請稍後再試。\n\n應用程式將在重新啟動時再次嘗試建立帳戶。"; +"failure.purchase.sandbox.message" = "所選的沙盒訂閱已不再提供。"; +"failure.redeem.invalid.title" = "無效的卡 PIN 碼"; +"failure.redeem.invalid.message" = "您似乎輸入了一個無效的卡 PIN 碼,請再試一次。"; +"failure.redeem.claimed.title" = "此卡已被使用"; +"failure.redeem.claimed.message" = "這張卡似乎已經被另一個帳戶使用。您可以嘗試輸入不同的 PIN 碼。"; +"failure.submit" = "返回"; + +"unreachable.vc_title" = "錯誤"; +"unreachable.title" = "噢!"; +"unreachable.message" = "找不到網路連線。請確定您已連線上網,然後點選下方按鈕重試。\n\n您可以稍後再回來完成程序。"; +"unreachable.submit" = "重試"; + +"purchase.uncredited.alert.message" = "您有未貸記的交易,要回復帳戶資料嗎?"; +"purchase.uncredited.alert.button.cancel" = "取消"; +"purchase.uncredited.alert.button.recover" = "回復帳戶"; + +"purchase.trials.intro" = "開始 7 天免費試用"; +"purchase.trials.price.after" = "然後 %@"; +"purchase.trials.money.back" = "30 天退款保證"; +"purchase.trials.1year.protection" = "1 年隱私權和身分保護"; +"purchase.trials.anonymous" = "匿名瀏覽並隱藏 IP。"; +"purchase.trials.devices" = "同時支援 10 台裝置"; +"purchase.trials.devices.description" = "同時為最多 10 台裝置提供保護。"; +"purchase.trials.region" = "可輕鬆連線到任何地區"; +"purchase.trials.servers" = "32 個國家超過 3300 台伺服器"; +"purchase.trials.start" = "開始訂閱"; +"purchase.trials.all.plans" = "檢視所有可用方案"; + +"purchase.subscribe.now" = "馬上訂閱"; + +// WALKTHROUGH + +"walkthrough.action.next" = "下一步"; +"walkthrough.action.done" = "完成"; +"walkthrough.action.skip" = "跳過"; + +"walkthrough.page.1.title" = "同時支援 10 台裝置"; +"walkthrough.page.1.description" = "同時為多達 10 台裝置提供保護"; +"walkthrough.page.2.title" = "輕易就能連線到任何地區"; +"walkthrough.page.2.description" = "我們的伺服器遍佈全球,能為您提供全面保護。"; +"walkthrough.page.3.title" = "讓自己免受廣告滋擾"; +"walkthrough.page.3.description" = "只要啟用我們的內容阻擋器,使用 Safari 瀏覽器時就再也不會看到廣告。"; + +"share.data.buttons.accept" = "接受"; +"share.data.buttons.noThanks" = "不了,謝謝"; +"share.data.buttons.readMore" = "閱讀更多內容"; +"share.data.text.title" = "請協助我們改善服務"; +"share.data.text.description" = "為了確保服務的連線品質,您可以匿名與我們分享您的連線統計資料。這些報告不會包含任何個人識別資訊。"; +"share.data.text.footer" = "您隨時都可以在設定中控制。"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings new file mode 100644 index 000000000..7d68e2272 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "版本 %@ (%@)"; +"global.close" = "關閉"; +"global.ok" = "確認"; +"global.cancel" = "取消"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings new file mode 100644 index 000000000..b4c846e04 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "登入帳戶"; +"login.username.placeholder" = "使用者名稱(p1234567)"; +"login.password.placeholder" = "密碼"; +"login.submit" = "登入"; +"login.restore.button" = "收不到帳戶資料?"; +"login.error.title" = "登入"; +"login.error.validation" = "您必須輸入使用者名稱及密碼。"; +"login.error.unauthorized" = "您的使用者名稱或密碼不正確。"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "使用購買收據登入"; +"login.magic.link.title" = "使用神奇的電子郵件連結登入"; +"login.magic.link.response" = "請確認電子信箱是否已收到登入連結。"; +"login.magic.link.send" = "傳送連結"; +"login.magic.link.invalid.email" = "無效的電子郵件。請重試。"; + +"purchase.title" = "選擇 VPN 方案"; +"purchase.subtitle" = "30 天退款保證"; +"purchase.email.placeholder" = "電子郵件地址"; +"purchase.continue" = "繼續"; +"purchase.login.footer" = "已有帳號?"; +"purchase.login.button" = "登入"; +"purchase.error.title" = "購買"; +"purchase.error.validation" = "必須輸入電郵地址。"; +"purchase.error.connectivity.title" = "連線失敗"; +"purchase.error.connectivity.description" = "我們無法連線至 Private Internet Access。這可能是因為您的網路連線狀態不佳,或我們的服務在您的國家遭到封鎖。"; +"purchase.confirm.form.email" = "請輸入您的電子郵件地址"; +"purchase.confirm.plan" = "您正在購買 %@ 方案"; +"purchase.email.why" = "請提供電子郵件以便我們傳送使用者名稱及密碼。"; +"purchase.submit" = "提交"; +"purchase.or" = "或"; + +"upgrade.header" = "歡迎回來!"; +"upgrade.title" = "如果要使用 Private Internet Access,您必須續訂。"; +"upgrade.renew.now" = "立即續訂"; + + + +"redeem.title" = "兌換禮品卡"; +"redeem.subtitle" = "於下方輸入您的電子郵件地址及禮品卡或試用卡並的 %lu 位數 PIN 碼。"; +"redeem.email.placeholder" = "電子郵件地址"; +"redeem.submit" = "提交"; +"redeem.error.title" = "兌換"; +"redeem.error.code" = "代碼必須包含 %lu 個數字。"; +"redeem.error.allfields" = "請輸入您的電子郵件地址及禮品卡 PIN 碼。"; +"redeem.accessibility.back" = "返回"; +"redeem.giftcard.placeholder" = "禮品卡 PIN 碼"; + +"plan.monthly.title" = "月繳"; +"plan.yearly.title" = "年繳"; +"plan.yearly.detail_format" = "每年 %@%@"; +"plan.price_format" = "每月 %@"; +"plan.best_value" = "最佳值"; +"plan.accessibility.per_month" = "/ 月"; + +"restore.title" = "回復未貸記購買項目"; +"restore.subtitle" = "如果您透過此應用程式購買方案後收不到您的憑證,可以透過這裡要求再次傳送。此操作不會收取任何費用。"; +"restore.email.placeholder" = "電子郵件地址"; +"restore.submit" = "確定"; + +"iap.error.message.unavailable" = "Apple 伺服器目前無法使用,請稍後再試。"; +"iap.error.title" = "錯誤"; + +"agreement.trials.title" = "免費試用條款與條件"; +"agreement.trials.message" = "確認購買後,系統將從您的 Apple ID 帳號收取費用。除非您在目前訂閱期間結束前至少 24 小時取消訂閱,否則訂閱將自動續訂。在目前期間結束前 24 小時內,將從您的帳號收取續訂費用。您可在購買後,前往 App Store 的帳號設定管理和取消您的訂閱。\n\n「特定付費訂閱」可能在以您的付費方式收費前,提供免費試用。若您在我們開始以您的付費方式收費前,決定取消「付費訂閱」,請在免費試用結束前至少 24 小時取消訂閱。\n\n只有新使用者才享有免費試用的資格,且我們擁有唯一決定權。若您試圖再次註冊免費試用,我們會立即以「標準訂閱費用」向您收費。\n\n我們保留隨時解除您免費試用的權利。\n\n若您的免費試用有任何未使用的期間,將會在購買訂閱時收回。\n\n若註冊即代表您接受此條款與條件。"; +"agreement.message" = "免費試用 7 天後,除非您在試用期結束前至少 24 小時取消訂閱,否則系統將自動續訂 %@,並在試用期結束前的 24 小時內,從您的 Apple ID 帳號收取續訂費用。購買後,您可以前往 App Store 的帳號設定管理或取消您的訂閱方案。每位用戶只有一次 7 天試用的機會。若您的免費試用有任何未使用的期間,將會在購買訂閱時收回。所有價格已包括適用於當地的營業稅。\n\n若註冊,即代表您已接受 $1 與 $2。"; +"agreement.trials.yearly.plan" = "年"; +"agreement.trials.monthly.plan" = "月"; + +"agreement.message.tos" = "服務條款"; +"agreement.message.privacy" = "隱私權政策"; + +"getstarted.buttons.buyaccount" = "購買帳戶"; + +"gdpr.collect.data.title" = "我們收集的個人資料"; +"gdpr.collect.data.description" = "電子郵件地址用於管理帳戶及防止濫用。"; +"gdpr.usage.data.title" = "我們收集個人資料的用途"; +"gdpr.usage.data.description" = "電子郵件地址僅用於傳送訂閱資訊、付款確認函、客戶通訊及 Private Internet Access 的促銷優惠。"; +"gdpr.accept.button.title" = "同意並繼續"; + +"update.account.email.error" = "無法修改帳戶電子郵件"; diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/Info.plist b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/Info.plist new file mode 100644 index 000000000..11c8b1225 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/Info.plist differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem new file mode 100644 index 000000000..82dec692d --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem @@ -0,0 +1,43 @@ +-----BEGIN CERTIFICATE----- +MIIHqzCCBZOgAwIBAgIJAJ0u+vODZJntMA0GCSqGSIb3DQEBDQUAMIHoMQswCQYD +VQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNV +BAoTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIElu +dGVybmV0IEFjY2VzczEgMB4GA1UEAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3Mx +IDAeBgNVBCkTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkB +FiBzZWN1cmVAcHJpdmF0ZWludGVybmV0YWNjZXNzLmNvbTAeFw0xNDA0MTcxNzQw +MzNaFw0zNDA0MTIxNzQwMzNaMIHoMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex +EzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNVBAoTF1ByaXZhdGUgSW50ZXJuZXQg +QWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UE +AxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBCkTF1ByaXZhdGUgSW50 +ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkBFiBzZWN1cmVAcHJpdmF0ZWludGVy +bmV0YWNjZXNzLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALVk +hjumaqBbL8aSgj6xbX1QPTfTd1qHsAZd2B97m8Vw31c/2yQgZNf5qZY0+jOIHULN +De4R9TIvyBEbvnAg/OkPw8n/+ScgYOeH876VUXzjLDBnDb8DLr/+w9oVsuDeFJ9K +V2UFM1OYX0SnkHnrYAN2QLF98ESK4NCSU01h5zkcgmQ+qKSfA9Ny0/UpsKPBFqsQ +25NvjDWFhCpeqCHKUJ4Be27CDbSl7lAkBuHMPHJs8f8xPgAbHRXZOxVCpayZ2SND +fCwsnGWpWFoMGvdMbygngCn6jA/W1VSFOlRlfLuuGe7QFfDwA0jaLCxuWt/BgZyl +p7tAzYKR8lnWmtUCPm4+BtjyVDYtDCiGBD9Z4P13RFWvJHw5aapx/5W/CuvVyI7p +Kwvc2IT+KPxCUhH1XI8ca5RN3C9NoPJJf6qpg4g0rJH3aaWkoMRrYvQ+5PXXYUzj +tRHImghRGd/ydERYoAZXuGSbPkm9Y/p2X8unLcW+F0xpJD98+ZI+tzSsI99Zs5wi +jSUGYr9/j18KHFTMQ8n+1jauc5bCCegN27dPeKXNSZ5riXFL2XX6BkY68y58UaNz +meGMiUL9BOV1iV+PMb7B7PYs7oFLjAhh0EdyvfHkrh/ZV9BEhtFa7yXp8XR0J6vz +1YV9R6DYJmLjOEbhU8N0gc3tZm4Qz39lIIG6w3FDAgMBAAGjggFUMIIBUDAdBgNV +HQ4EFgQUrsRtyWJftjpdRM0+925Y6Cl08SUwggEfBgNVHSMEggEWMIIBEoAUrsRt +yWJftjpdRM0+925Y6Cl08SWhge6kgeswgegxCzAJBgNVBAYTAlVTMQswCQYDVQQI +EwJDQTETMBEGA1UEBxMKTG9zQW5nZWxlczEgMB4GA1UEChMXUHJpdmF0ZSBJbnRl +cm5ldCBBY2Nlc3MxIDAeBgNVBAsTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAw +HgYDVQQDExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UEKRMXUHJpdmF0 +ZSBJbnRlcm5ldCBBY2Nlc3MxLzAtBgkqhkiG9w0BCQEWIHNlY3VyZUBwcml2YXRl +aW50ZXJuZXRhY2Nlc3MuY29tggkAnS7684Nkme0wDAYDVR0TBAUwAwEB/zANBgkq +hkiG9w0BAQ0FAAOCAgEAJsfhsPk3r8kLXLxY+v+vHzbr4ufNtqnL9/1Uuf8NrsCt +pXAoyZ0YqfbkWx3NHTZ7OE9ZRhdMP/RqHQE1p4N4Sa1nZKhTKasV6KhHDqSCt/dv +Em89xWm2MVA7nyzQxVlHa9AkcBaemcXEiyT19XdpiXOP4Vhs+J1R5m8zQOxZlV1G +tF9vsXmJqWZpOVPmZ8f35BCsYPvv4yMewnrtAC8PFEK/bOPeYcKN50bol22QYaZu +LfpkHfNiFTnfMh8sl/ablPyNY7DUNiP5DRcMdIwmfGQxR5WEQoHL3yPJ42LkB5zs +6jIm26DGNXfwura/mi105+ENH1CaROtRYwkiHb08U6qLXXJz80mWJkT90nr8Asj3 +5xN2cUppg74nG3YVav/38P48T56hG1NHbYF5uOCske19F6wi9maUoto/3vEr0rnX +JUp2KODmKdvBI7co245lHBABWikk8VfejQSlCtDBXn644ZMtAdoxKNfR2WTFVEwJ +iyd1Fzx0yujuiXDROLhISLQDRjVVAvawrAtLZWYK31bY7KlezPlQnl/D9Asxe85l +8jO5+0LdJ6VyOs/Hd4w52alDW/MFySDZSfQHMTIc30hLBJ8OnCEIvluVQQ2UQvoW ++no177N9L2Y+M9TcTA62ZyMXShHQGeh20rb4kK8f+iFX8NxtdHVSkxMEFSfDDyQ= +-----END CERTIFICATE----- diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA.der b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA.der new file mode 100644 index 000000000..1bbbe477d Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA.der differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory new file mode 100644 index 000000000..bccd33843 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements new file mode 100644 index 000000000..dbf9d6144 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 new file mode 100644 index 000000000..f790851d8 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 differ diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources new file mode 100644 index 000000000..2113d6bd3 --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources @@ -0,0 +1,128 @@ + + + + + files + + PIA-RSA-4096.pem + + 3qHvNikZqOiKtbZEW5+oygpFyfw= + + PIA.der + + HjU73bSJKXFVdCTqzHVin0iWAak= + + + files2 + + PIA-RSA-4096.pem + + hash + + 3qHvNikZqOiKtbZEW5+oygpFyfw= + + hash2 + + Mumx0UM+qXYU8qFMbjWOP1fAVwzJ9rLugSaZumlsZqs= + + + PIA.der + + hash + + HjU73bSJKXFVdCTqzHVin0iWAak= + + hash2 + + H9JWWEVuqzBB+6d8zTmKuBJO3MG4svwdVf32sbv8nXA= + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature new file mode 100644 index 000000000..e69de29bb diff --git a/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/_CodeSignature/CodeResources b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/_CodeSignature/CodeResources new file mode 100644 index 000000000..6ae27bdaa --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIA VPN WG Tunnel.appex/_CodeSignature/CodeResources @@ -0,0 +1,1745 @@ + + + + + files + + Info.plist + + bCdKd9zhLFhkSgnfY1ayTtWs7BU= + + PIALibrary_PIALibrary.bundle/Assets.car + + 8h6Hyf4U9/+JlpRmAN3vBaPEjrw= + + PIALibrary_PIALibrary.bundle/Info.plist + + U4V2uvQAAIulAUfBSoJQTzWiVN4= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + dytHgVNc10hWhKQW+WIDasbWdTU= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib + + OVb1ASokoqm9FsqgYqS4ykOLvTk= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + qEnPzvZ7YJ2malb9v8b6uU1qRtI= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib + + BnH89TJFPy09hwlepgmy1qX8w5I= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist + + tvSnglTgEmfEVDs4Pqzq89zCWdk= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + htQTSxHbapTjr/KU4MZ+BReh+fg= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + CJa19sBIiRCsSpkmvlAK9WVgIUc= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib + + DClrKMNBhP7R57XPbVZNLZEkhHY= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib + + RII82MT1u8xiVhoF6z8GAPWRauw= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + YpRMevT/Hk92B7qxIoBZNubmhVo= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + bJ8pWQoqUwPJh2R449Z5iB80fgw= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + XIT4vTE0sbcaxPw4Ukcc10AudMU= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + 8QYAr5CSJVq9J2M/WNeKrHxyH4k= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + /KugdZ7rq/us89d7xS8Y4W80uoE= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + lAQN56rjGXobwkMhOfbs34FT+S8= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist + + /pYtZWavELI0+6nEkTUa0WNFSew= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + QLgeyu0ZVc/lDmyITQfrBSRT2Hk= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + gA8eOIpUQd1BEBgO/w9hDFS+JxU= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + GzhYGB3AyZ0wytBn61POuwdsJ7E= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + sQtUseVfpjT4CFtCBgvBwDjWfQA= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory + + gjf0PUSrcJskfjBJ7fSOp0hPRqU= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements + + OnX22wWFKRSOFN1+obRynMCeyXM= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 + + Xek7S2WT/EJTVDHjzmsxCQMBPMg= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources + + ypAPfIR7Xyk9v8RohL9v2uz3dB4= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature + + 2jmj7l5rSw0yVb/vlWAYkK/YBwk= + + PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings + + hash + + KDACaW+muq3Q7S2KFi/tSoBrOA0= + + optional + + + PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings + + hash + + q69blyRGQI14B9CBKT9Rsw4dq0k= + + optional + + + PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings + + hash + + BkACZwewt5pWHuYeiW8u/ttymCg= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings + + hash + + ImqHeuQyhd4vbb7tX6gDpc0Uws4= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/UI.strings + + hash + + JEB6TYMiWHIJ3Fwzv9hwS3X5B9c= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings + + hash + + 0U+OaxIpF3m54GcZw6Rj0FT9IQU= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings + + hash + + ULQLCKJ1Tkx5LYNqw+wZAPpz+fc= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/UI.strings + + hash + + 1964G9tW/vLUljfWDybLqmj8ovo= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings + + hash + + j/jLkt7lT5WaqzpSmS2HeZ2YT7g= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings + + hash + + EZ9QZ7PSibfcWSeEETK4rR/PkKE= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/UI.strings + + hash + + 8v4J37YS+jZq3LBvpRfFdfrmOjo= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings + + hash + + BwdYyKtC03avQBNFX31HfqSElzI= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings + + hash + + /cuvVUGtYOlubi9pgRpN8GF6eaQ= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings + + hash + + iiP5bcCQB5ClycQCkVGeHIMUAks= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings + + hash + + lx4/QzIqPJcVTvU4PUA9DuA+iR0= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings + + hash + + vRPh7xNvA8CBlDbvqId98Ppaol4= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings + + hash + + IbgvE2UN4PxyRd+exu9NKENUaI0= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings + + hash + + KoygslQ7+C06O61A0YHLMJPIhd8= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings + + hash + + Ed4oYGhilkGVvO6AshjBjzdE+7w= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/UI.strings + + hash + + Y50/iDsqGezjtBuqSlPo8jymMAc= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings + + hash + + 8OHVfUCzQp3y5Avt0qvL0KEijp8= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings + + hash + + nNEDjklKvB3EYDy3z/dKvk0Y3Sc= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings + + hash + + +2YIistydmlPjDts2u1ROqKtWqI= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings + + hash + + RbM1jidNxxT0GrCW5Bp4AJ2C10U= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings + + hash + + v+qEVshU1lPCEIX6p/5VNVvHCsE= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings + + hash + + XSewfIvou+2vfPzfd4L1JobLejU= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings + + hash + + j/ZhhE8EhAk/Lumf0d8hAl0mnM0= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings + + hash + + KhJ/QqRfNp4OZfzpif4GtcBF8bI= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings + + hash + + xDMWYimFFDfSHhe2YZpdtrl2g8k= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings + + hash + + uwWBmqf4ftnCEhc6CREp8ByROW4= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings + + hash + + NyXHmGW4hA/Eauh4ij9O5S5WhTA= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings + + hash + + YZpZdbu3r3xtH/jvKMalDSa3lOc= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings + + hash + + yqehLrthKrrux3wlT4BXD2o86VM= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings + + hash + + 6OMfwEOtzCuZV03uZytGep2fVcM= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings + + hash + + K6FfGb4sRyZ+8fUCnq80qKRGipc= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings + + hash + + jdPps229/rIXz+/ddHNG9FuKBhQ= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings + + hash + + fbM6TjAWhkqwQRqlFgXqxwrx+8k= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings + + hash + + 5JKfMEQAm3AUcBKlsob0yfJRkQk= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings + + hash + + 01ji1w1oANjR7h5TRr6cBlyaRGo= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings + + hash + + ZPLrICgFyE180EQFQQsAPW2T0LY= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings + + hash + + Ke55XO9cpqEQhKUHTr3HEvi0aUM= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings + + hash + + rfmjmvw733cPOhxZ0RizNQfXkSE= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings + + hash + + awJpWTrrqH31sd1t1ndiEy4cN/A= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/UI.strings + + hash + + QMaBIt1A8kjNOstov8L0lchT5Ec= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings + + hash + + 5J5E4i04UUqsWy3SQZN1zcKIZaQ= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings + + hash + + 55QLf0o5XG8IWfXbQ6KvFWToA+4= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings + + hash + + hfdFuAQLTfdHleeMkh4YCtlcNBY= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings + + hash + + R49azaTbZXexzZ4fO2KAO8IQIW4= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings + + hash + + B3OiNtJOoqFlNs77EeQh3/YlwiU= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings + + hash + + athEoNydnFVAkLxqKvlUTv5EfZg= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings + + hash + + 6aHDe64C6X+IcTDg3C39b+SM9Ls= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings + + hash + + InQh2yXFC6brp+xf2gtnVDZtsuY= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings + + hash + + 7NuRLJG/PUbRlsl/6dZTfboVNfQ= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings + + hash + + hBHKqa7nicnE6j15W8iBNQQdsws= + + optional + + + PIAWireguard_PIAWireguard.bundle/Info.plist + + /Sr7lQ3v9dlVi0s0lsUfQz9dK84= + + PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem + + 3qHvNikZqOiKtbZEW5+oygpFyfw= + + PIAWireguard_PIAWireguard.bundle/PIA.der + + HjU73bSJKXFVdCTqzHVin0iWAak= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory + + 1goWa+U5od4AnpP1zIi6N43ps+k= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements + + OnX22wWFKRSOFN1+obRynMCeyXM= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 + + ae4UnuV7lDFjF1toM8Tj2NbLvS4= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources + + G9y6xZfvG8s3gN1rZw4IpRPNIIc= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature + + 2jmj7l5rSw0yVb/vlWAYkK/YBwk= + + + files2 + + PIALibrary_PIALibrary.bundle/Assets.car + + hash2 + + z2oHVz8/itmR3oqHY51lv6NTMX9epuIIiBsUG+B3f3M= + + + PIALibrary_PIALibrary.bundle/Info.plist + + hash2 + + WFu/u2EPoebomnmaiyenOb8Mi4SrKw4owMy0mxtgPuY= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + hash2 + + EHhu+ZyC8bLdGTREBf6He41YqGou0HpQDQ4u1t+B67c= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib + + hash2 + + Rr/ex+JnT00WjY8BTVZWRNqz/GfU4jaR3v03FmrukIA= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + hash2 + + fkNfOkKA9R7NGpPPFiVhuYQ2+AdSVeR9osgZyyAms58= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib + + hash2 + + hDcEgabY8XWIV+bMHjY9T2LEXhXGYAjSsL1LyHygu1A= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist + + hash2 + + +ULlbQDKRqZAgLPRQ4aWV271svAlSIpTvPj8fAxklSA= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + hash2 + + vqbeJEql0Jgydj1T24xy6xJbrXkBGPmYusMqnTCSGcM= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + hash2 + + 28vreA7cNtWCBn0Hh2oGxsleKe0mqFxApasYvvlSWTo= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib + + hash2 + + FLZ/2WLEaK53aWKIJqX9T7ltNA15ERKTr7oZHeg14vU= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib + + hash2 + + 7XhIk/s4X/sIr5xEWP1PVGI7EV+vDS5HktrZ/OskXUk= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + hash2 + + N91d6/YhJJHCGX6EQSKWaoeSLBzL4sitnyKgo7IerzU= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + hash2 + + LmfITndcyawR5vC3q1+ZA3Tmezvc/H/UOm9eNi8rkXQ= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + hash2 + + cxj3iSMzDtgAEjJCn2Kh4wOxq643eP+NVKmuyRy4ScE= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + hash2 + + +pb1yeNeVETkzR3D7bHHd7b/7ckHANG2FYkou4fexeA= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + hash2 + + LcuEIHcg/ABNnzlBcFJUh1QnZG6OeeODUinCRME6gVM= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + hash2 + + 2sqAv9sKlmNLJyLvObb9ssgf6q3St0BYeyc41iKo10w= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist + + hash2 + + Y3Hpojl68zniB+aUL9PZXEVKtWuzsnlbS5/xAZKFhAo= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + hash2 + + rvJVcZPH3KzWKHiwzq/TcFc5ZloThq9gqavWaC6uX0s= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + hash2 + + 7V3P3q8VYMDAWwvrjqD85I4/kwFbGlegJ76JkMn8sDc= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + hash2 + + ZXVhR7A3IzlBTiK3AT8wLUDQeJhM59ywT6AJJWSHNuE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + hash2 + + gE07Q/56h7roPAuaRZhMhxJ+wNhM0gvRduQ2/Him9z8= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory + + hash2 + + okxh/GX6INtaXI5mCHxoHTTaQyHkvI6ouJ+gLzrnNDE= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements + + hash2 + + mHkgkE6rZQ51eIwFSqCwUk5qgL/HGqMt+NI3phdD+YY= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 + + hash2 + + lLcvw56pfEheqGNbi4m/Vp+O5ghlDPZzLW3I4aJ+Y/o= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources + + hash2 + + klaP6QnT3PPiOIqDEsVyy6EZJohkwril3bMp1OxL7PA= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature + + hash2 + + 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= + + + PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings + + hash2 + + /PdaPdFVdwwWy0WMwLSdWCQv9CkI1tpm2JyG/6Tmn9M= + + optional + + + PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings + + hash2 + + YhKnZ6a5ITfwAgnv/6Cd1x+TPQ067/rO+K+rWNEzD6w= + + optional + + + PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings + + hash2 + + S1/lODt2iX9EyVMvBt0dsAV6rYE8BdXAlCaTa1+HTsw= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings + + hash2 + + +bSgSn+Mt62wraeSALDwHwkp4db5Q4ig2thAObbQPnc= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/UI.strings + + hash2 + + doJ3NS9+wFy5hCKe75hwGTA8tafBSrCQJnnrwcghQQs= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings + + hash2 + + udZzYVGokipS7z20EPQUqoeoTxmet5LGclYicXo/Qzc= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings + + hash2 + + 3qf/FrW+/u8t/lO9wA/+NtfCBtCJ1WguXGz2uvwUoc0= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/UI.strings + + hash2 + + OqXvZaKPjVRbECIamvYeVtO1k5SXy41xBrfoDBODJzU= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings + + hash2 + + /RCU9b12hOYxRv0uKqNRMyGNoOs2qGmTkLw0Js7xFcQ= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings + + hash2 + + eTcLQYTr4H9oZFv0rxYaq3gQ+WhpLjFnSyzwaOIiehc= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/UI.strings + + hash2 + + 2LmfTdHJMvlivEZbaU9xSJAAnvlpBpvBa+WumfJ+Zbs= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings + + hash2 + + oAZWhsRhLpQkW9ZhuKf4MOb41w5Y8MZPZx3S0NMM5tk= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings + + hash2 + + nI1MegvByIjofRyKN8F43cuCTWoXr5uIExtoQ3BK6NM= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings + + hash2 + + a8Vp2K22QfOvNgn1DCjRhoTHkZVdwywOmftje9rC42Y= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings + + hash2 + + mxe8YvU0Z6ToCEE2d86cOJNrmOVz8cRCJpBzDQWLVWc= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings + + hash2 + + QqrxBLWpNYv5rrqBFN8BLC6LNXUmQVa74Gl+0ksKBZU= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings + + hash2 + + Pv8eZpPXvR5mqm53bwD8agrzEaWy3xj6YdWgIOflm+M= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings + + hash2 + + xyVMkl7jhNBZ/vN0ZFmM2FlY8ovTdbitINQqEgRyqks= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings + + hash2 + + VlWjS5dJ4UNfaNhHqlxeKfkECiko5YzTss4+zOmzYJ4= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/UI.strings + + hash2 + + y2JDFhY4F9hvHbr4F4pF6PrFuy4JUyVFpMw8BcbSBY4= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings + + hash2 + + lu+ZwHtxRo9m+9fmCbojh8YbdagKuR6eYwXH/O4QNHo= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings + + hash2 + + bDq3nM4T1ut8Ts8+QYkxdWNGRu+//zSf189mi3aRlQ8= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings + + hash2 + + YaeZ3JgOA+qIusYRqxxG6pwBkrFim1rw7qTyLnl060I= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings + + hash2 + + Xq2cl5IrUxxaYjKRRxrCcWp8u2KzQtjBAPMG2ywwICA= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings + + hash2 + + tGa6ibOVYp6N7/L++jdOleoT9KE1QQ1PK1rhzpVOKDQ= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings + + hash2 + + QIUwyVItXRoQKXGmgHFFotXmiOSE9JxkZlaoE2IHX+8= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings + + hash2 + + weQQxyn+b2SpWKeGAvJqE/ii7MCRaDRxNADg8r9TvYI= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings + + hash2 + + RnLEv00iw5lOIGL/XJzJU1ShBwn9hBnC4hNhikuyhA4= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings + + hash2 + + CbdEeBsje8P4+h3x6IQ57ZROUQ898FBunnH3ZY69DnQ= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings + + hash2 + + 3l4+0NbmewoK9l0/qdkIGPcqqrLIRM5eOrwPHGkUEy0= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings + + hash2 + + VfV2uL8OKA5ZiR3yiHFT65ZEHaCbkn35Yo+ur18Bqxw= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings + + hash2 + + 69DUk8Zeh5SReiVA+Wk9iHozzU98pp8V8uFeG+EA+A0= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings + + hash2 + + LHqIVFxiS7xOGRDl+Mc94nzpdWHZpV7V+YNrcO3F6rw= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings + + hash2 + + me1r0CSvQxGrjhri1zbZY30vF6XWxdoV5q/XNHlGVhs= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings + + hash2 + + frs+aVxqmI1A7qNQ3lTqmaN+e68SScT1D6TutOPSHFs= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings + + hash2 + + xQJW7uzg6y9kJf1gLZnCM9oO+0wQ84AayU+o+TV5Y2I= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings + + hash2 + + MnV7VMLXWFm/KNE5a8UHkxR04f0OznpqoK1+9hyw8zY= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings + + hash2 + + DxvjdPIJCkbOywZjS5+ayQkGKWHlrGcquTxizAdezyg= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings + + hash2 + + LDC5bZkG2h8AgTQLoL1yMj6JJA/ir2Qs9YoX0A27QLc= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings + + hash2 + + WWOM/zJIvlgQASAWOk/VrhJ76xkmJSNIM383qyAebmY= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings + + hash2 + + oSkpUWDyzNoWL+/tE+JqlzA0l5XGRGrg0sa5Gvpc4eA= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings + + hash2 + + NeG7RvpFs7aBDoclE4CeSnfGf9AS7tGvjGr/m1zT3eY= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings + + hash2 + + buuAYnSRdzIW7wnFAfyIoc2xNnPeH6VmMpaTl1UnDcI= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/UI.strings + + hash2 + + 86j7ej1K8vjK2Wc+4VvI8COo0F5VNrFgab6jFb52UQM= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings + + hash2 + + CWB5kJ7tdPh65LpMEk7ON91tZXYPjCLHG3+KYt/Wor8= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings + + hash2 + + J7rTcADNQWVMdE7ToyJl5ztWFP7nS0LpgiIcVb4D/H8= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings + + hash2 + + mn9KO/anRw5JkawqXZT06MvC8pSCiTjPxNb+c3RrZ1I= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings + + hash2 + + 3U8T+edoinqQskEd4Y8vg0sVEFsjDRp4YCrhcTIq0Nw= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings + + hash2 + + 92+yGo0u+BgXiVmoYH9vE1wxCXffUp20Eb5V8JkLJDU= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings + + hash2 + + iDsYoUTxx8POedODQmaipEBJukmHm0klpri/JSYxzCg= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings + + hash2 + + NtHmRVKzAicr7H8AVAqK8Bni236Z2cMnLjdcG/U7T6M= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings + + hash2 + + ajON8rkioyflp0u9oIDFniyq4zryBG0tC/51c7OOzbY= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings + + hash2 + + IvX18xiU0gageVb9uJLXqnoj5htrqNqSWI1LCqnTWY0= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings + + hash2 + + E7PBBBbQdDJESlMtJW1vcQ17At7XbJBTHK0Mbm0eyU0= + + optional + + + PIAWireguard_PIAWireguard.bundle/Info.plist + + hash2 + + mwC94dBByVRThcNBnzQ+IGHCLsHQKv9SdkUi4cOLyI4= + + + PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem + + hash2 + + Mumx0UM+qXYU8qFMbjWOP1fAVwzJ9rLugSaZumlsZqs= + + + PIAWireguard_PIAWireguard.bundle/PIA.der + + hash2 + + H9JWWEVuqzBB+6d8zTmKuBJO3MG4svwdVf32sbv8nXA= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory + + hash2 + + 0YGO8yzUacVLcwaChXyFEDV700SjEoA3y4jHNuxE/nQ= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements + + hash2 + + mHkgkE6rZQ51eIwFSqCwUk5qgL/HGqMt+NI3phdD+YY= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 + + hash2 + + tlUOZy9wXXkJrqlFG78GXGAwhg6PtVrzl/M9S9NNm64= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources + + hash2 + + JoxbI6Yk1SD3A2j4qcD82qxRn61PU0HoJwlTobmuafE= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature + + hash2 + + 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/Assets.car b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/Assets.car new file mode 100644 index 000000000..e14504a9d Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/Assets.car differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/Base.lproj/PIAWidget.intentdefinition b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/Base.lproj/PIAWidget.intentdefinition new file mode 100644 index 000000000..b464c63ab --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/Base.lproj/PIAWidget.intentdefinition @@ -0,0 +1,63 @@ + + + + + INEnums + + INIntentDefinitionModelVersion + 1.2 + INIntentDefinitionNamespace + 88xZPY + INIntentDefinitionSystemVersion + 22G120 + INIntentDefinitionToolsBuildVersion + 15A240d + INIntentDefinitionToolsVersion + 15.0 + INIntents + + + INIntentCategory + information + INIntentClassPrefix + PIA + INIntentDescriptionID + tVvJ9c + INIntentEligibleForWidgets + + INIntentHash + 13847754579712971916 + INIntentIneligibleForSuggestions + + INIntentName + Configuration + INIntentResponse + + INIntentResponseCodes + + + INIntentResponseCodeName + success + INIntentResponseCodeSuccess + + + + INIntentResponseCodeName + failure + + + + INIntentTitle + PIA VPN + INIntentTitleID + gpCwrM + INIntentType + Custom + INIntentVerb + View + + + INTypes + + + diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/Info.plist b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/Info.plist new file mode 100644 index 000000000..b1327982b Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/Info.plist differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/PIAWidgetExtension b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/PIAWidgetExtension new file mode 100755 index 000000000..7aba669b0 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/PIAWidgetExtension differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/_CodeSignature/CodeResources b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/_CodeSignature/CodeResources new file mode 100644 index 000000000..b26d8a67d --- /dev/null +++ b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/_CodeSignature/CodeResources @@ -0,0 +1,448 @@ + + + + + files + + Assets.car + + vBNI4c3x6TEPyDIB9amVjE8MBJY= + + Base.lproj/PIAWidget.intentdefinition + + zKcNL89QiaANd0DXGfqWn47GOnk= + + Info.plist + + fTJ7PehK4e2nU10GoLdOc+jfTr8= + + ar.lproj/Localizable.strings + + hash + + Md6QT7nIXXDk61r6o83jOaoWi+0= + + optional + + + da.lproj/Localizable.strings + + hash + + CTDN1XeuYiB1Dn4x9l3Cjn7SKv8= + + optional + + + de.lproj/Localizable.strings + + hash + + 8/nukEsYQ4vBEUDnlPSkyIjQ2DA= + + optional + + + en.lproj/Localizable.strings + + hash + + AJXWjNsRROlJEGZeFrb111WXA44= + + optional + + + es-MX.lproj/Localizable.strings + + hash + + +dHYJ81rLTFc7oKY3/pbEW2skUk= + + optional + + + fr.lproj/Localizable.strings + + hash + + 9Eefd/eagluOmcPRDhlxT3YuWfM= + + optional + + + it.lproj/Localizable.strings + + hash + + gynEJhQ4J0z8hbym4dAdsmwTksI= + + optional + + + ja.lproj/Localizable.strings + + hash + + 5GPLw4+YK+7mnET38TEEzhsKwYk= + + optional + + + ko.lproj/Localizable.strings + + hash + + mqm3uu4o2lIi8bzz58Ii/Rdi9oo= + + optional + + + nb.lproj/Localizable.strings + + hash + + BwL+yuRj49Rm6s6nM7nvnL+58W0= + + optional + + + nl.lproj/Localizable.strings + + hash + + fenhiY0m5ubSFhtYN+ro2CZaG28= + + optional + + + pl.lproj/Localizable.strings + + hash + + nBjLPFE5/KP+kmCGvxqF3bwczjI= + + optional + + + pt-BR.lproj/Localizable.strings + + hash + + dWPcM+tXr9hodLfIAwkNjectrBQ= + + optional + + + ru.lproj/Localizable.strings + + hash + + kAdbQQhGPzEm9H/X6buQTzv3u6w= + + optional + + + th.lproj/Localizable.strings + + hash + + rZJba2j4PMzgaYRjn1/bLJcTKzY= + + optional + + + tr.lproj/Localizable.strings + + hash + + +sGzQAimWS3xf7hW1Vr+7QtVHQk= + + optional + + + zh-Hans.lproj/Localizable.strings + + hash + + XHPmF5td4UsQ+XrYF6tNWQaM0QA= + + optional + + + zh-Hant.lproj/Localizable.strings + + hash + + Ry9RWHjEmPc/PwrKkrtt8PF+hiI= + + optional + + + + files2 + + Assets.car + + hash2 + + VQNnVCtvOsDVJq1++unWMcNu4WBXNcTuaFwQPbbU1n4= + + + Base.lproj/PIAWidget.intentdefinition + + hash2 + + 3kTE3lnrdUUlB5l1V5RREqCTVZNj9Txej0o15P1yvZ0= + + + ar.lproj/Localizable.strings + + hash2 + + IkNNXKfp6fE3oi995oVW7WS2woZ1V9mCTjT63KoD9Ek= + + optional + + + da.lproj/Localizable.strings + + hash2 + + hktvifgzwYUEObgL+klKwiciZXViqYoni4mEvyH/eDM= + + optional + + + de.lproj/Localizable.strings + + hash2 + + eZeauJl1WUEhbBCXDPq2g72GSa4n2ti5+Pxu6lguAHM= + + optional + + + en.lproj/Localizable.strings + + hash2 + + fIKEDxEDw26xFvpU5X4CzlGLlP1HJe8GFPiZmM9lmFI= + + optional + + + es-MX.lproj/Localizable.strings + + hash2 + + YO/BsBVDZg45VDh/n8em6b1jsIYaOrn8GOq/m5FS55U= + + optional + + + fr.lproj/Localizable.strings + + hash2 + + lLmdgPx54cHu/haDrAHx1HPguOP+V194C5zkRchPa4U= + + optional + + + it.lproj/Localizable.strings + + hash2 + + i8JZceIPBoBOnxYZPIMHIjJFfomuK99fOu1BWI8qYN8= + + optional + + + ja.lproj/Localizable.strings + + hash2 + + q1vazqX4WtbkwrkcAXc3G1cZ9NQ7YqR527Y7LmvcFDE= + + optional + + + ko.lproj/Localizable.strings + + hash2 + + Fe5/oYfvjXJchN67Cszo0WFdq6ZKToUQ2MkR5E+pIOw= + + optional + + + nb.lproj/Localizable.strings + + hash2 + + +dvIfnHZPLTlDdlCXi1Wyq8OrjFIodLTXRMymQDDdzs= + + optional + + + nl.lproj/Localizable.strings + + hash2 + + QBgW2thYGHi8Edrc3QnU/DsqQKMD8x60oH3ZtANVl50= + + optional + + + pl.lproj/Localizable.strings + + hash2 + + VgmVDXw7qaceniPAafqE1JWUB2v43XlSajhyklliGcU= + + optional + + + pt-BR.lproj/Localizable.strings + + hash2 + + fgG0D/JPPGaD+yPyuPvOR7oxENubkXLPpxTkxIOVkkU= + + optional + + + ru.lproj/Localizable.strings + + hash2 + + 4N/PF7IV08Kniait/Y3VwKIWRr9fagf3ieIVPSfi2Hk= + + optional + + + th.lproj/Localizable.strings + + hash2 + + XlRWvXzghm9szK5CED5h9yPdxF6uN2/66uugdDNg7i8= + + optional + + + tr.lproj/Localizable.strings + + hash2 + + FVRguhv5tetKyZaue31PT6622CPyibxwLQG3ElD9dio= + + optional + + + zh-Hans.lproj/Localizable.strings + + hash2 + + FJgmrZ6Fx0JYezPV3t2BnB2JrCqrFL2KNB/cLzsBgCA= + + optional + + + zh-Hant.lproj/Localizable.strings + + hash2 + + C1tzFGWrx6ug/O2kor4GCyz/IhltGaWhQDoD4r5fJqw= + + optional + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/ar.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/ar.lproj/Localizable.strings new file mode 100644 index 000000000..72f251cba Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/ar.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/da.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/da.lproj/Localizable.strings new file mode 100644 index 000000000..da84165f3 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/da.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/de.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/de.lproj/Localizable.strings new file mode 100644 index 000000000..e96d881b7 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/de.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/en.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/en.lproj/Localizable.strings new file mode 100644 index 000000000..b8cb811ae Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/en.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/es-MX.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/es-MX.lproj/Localizable.strings new file mode 100644 index 000000000..2ba8b2a4b Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/es-MX.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/fr.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/fr.lproj/Localizable.strings new file mode 100644 index 000000000..be5e0d3d8 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/fr.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/it.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/it.lproj/Localizable.strings new file mode 100644 index 000000000..2c200bad3 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/it.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/ja.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/ja.lproj/Localizable.strings new file mode 100644 index 000000000..54e000008 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/ja.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/ko.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/ko.lproj/Localizable.strings new file mode 100644 index 000000000..6bc04227c Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/ko.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/nb.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/nb.lproj/Localizable.strings new file mode 100644 index 000000000..6f0dec437 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/nb.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/nl.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/nl.lproj/Localizable.strings new file mode 100644 index 000000000..87038baa2 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/nl.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/pl.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/pl.lproj/Localizable.strings new file mode 100644 index 000000000..6079451a9 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/pl.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/pt-BR.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/pt-BR.lproj/Localizable.strings new file mode 100644 index 000000000..9f5f6f8b8 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/pt-BR.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/ru.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/ru.lproj/Localizable.strings new file mode 100644 index 000000000..1a694cc7e Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/ru.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/th.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/th.lproj/Localizable.strings new file mode 100644 index 000000000..cc9175d02 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/th.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/tr.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/tr.lproj/Localizable.strings new file mode 100644 index 000000000..a9d781293 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/tr.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/zh-Hans.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/zh-Hans.lproj/Localizable.strings new file mode 100644 index 000000000..bc047f587 Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/zh-Hans.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/zh-Hant.lproj/Localizable.strings b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/zh-Hant.lproj/Localizable.strings new file mode 100644 index 000000000..e9ab32d0d Binary files /dev/null and b/PIA VPN dev.app/PlugIns/PIAWidgetExtension.appex/zh-Hant.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/QuickConnectTile.nib b/PIA VPN dev.app/QuickConnectTile.nib new file mode 100644 index 000000000..4b0b95ff9 Binary files /dev/null and b/PIA VPN dev.app/QuickConnectTile.nib differ diff --git a/PIA VPN dev.app/QuickConnectTileCollectionViewCell.nib/objects-12.3+.nib b/PIA VPN dev.app/QuickConnectTileCollectionViewCell.nib/objects-12.3+.nib new file mode 100644 index 000000000..06c2d4bab Binary files /dev/null and b/PIA VPN dev.app/QuickConnectTileCollectionViewCell.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/QuickConnectTileCollectionViewCell.nib/runtime.nib b/PIA VPN dev.app/QuickConnectTileCollectionViewCell.nib/runtime.nib new file mode 100644 index 000000000..f8b864a3b Binary files /dev/null and b/PIA VPN dev.app/QuickConnectTileCollectionViewCell.nib/runtime.nib differ diff --git a/PIA VPN dev.app/QuickSettingsTile.nib b/PIA VPN dev.app/QuickSettingsTile.nib new file mode 100644 index 000000000..9a5dd848e Binary files /dev/null and b/PIA VPN dev.app/QuickSettingsTile.nib differ diff --git a/PIA VPN dev.app/QuickSettingsTileCollectionViewCell.nib/objects-12.3+.nib b/PIA VPN dev.app/QuickSettingsTileCollectionViewCell.nib/objects-12.3+.nib new file mode 100644 index 000000000..32f7409b8 Binary files /dev/null and b/PIA VPN dev.app/QuickSettingsTileCollectionViewCell.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/QuickSettingsTileCollectionViewCell.nib/runtime.nib b/PIA VPN dev.app/QuickSettingsTileCollectionViewCell.nib/runtime.nib new file mode 100644 index 000000000..2971d575c Binary files /dev/null and b/PIA VPN dev.app/QuickSettingsTileCollectionViewCell.nib/runtime.nib differ diff --git a/PIA VPN dev.app/RegionTile.nib b/PIA VPN dev.app/RegionTile.nib new file mode 100644 index 000000000..607704998 Binary files /dev/null and b/PIA VPN dev.app/RegionTile.nib differ diff --git a/PIA VPN dev.app/RegionTileCollectionViewCell.nib/objects-12.3+.nib b/PIA VPN dev.app/RegionTileCollectionViewCell.nib/objects-12.3+.nib new file mode 100644 index 000000000..1f58a0d47 Binary files /dev/null and b/PIA VPN dev.app/RegionTileCollectionViewCell.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/RegionTileCollectionViewCell.nib/runtime.nib b/PIA VPN dev.app/RegionTileCollectionViewCell.nib/runtime.nib new file mode 100644 index 000000000..73dffb67e Binary files /dev/null and b/PIA VPN dev.app/RegionTileCollectionViewCell.nib/runtime.nib differ diff --git a/PIA VPN dev.app/Regions.json b/PIA VPN dev.app/Regions.json new file mode 100644 index 000000000..d985d5d3d --- /dev/null +++ b/PIA VPN dev.app/Regions.json @@ -0,0 +1 @@ +{"groups":{"ikev2":[{"name":"ikev2","ports":[500,4500]}],"meta":[{"name":"meta","ports":[443,8080]}],"ovpntcp":[{"name":"openvpn_tcp","ports":[80,443,853,8443]}],"ovpnudp":[{"name":"openvpn_udp","ports":[8080,853,123,53]}],"proxysocks":[{"name":"socks","ports":[1080]}],"proxyss":[{"name":"shadowsocks","ports":[443]}],"wg":[{"name":"wireguard","ports":[1337]}]},"regions":[{"id":"nl_amsterdam","name":"Netherlands","country":"NL","auto_region":true,"dns":"nl-amsterdam.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"84.247.116.222","cn":"amsterdam403"}],"meta":[{"ip":"143.244.41.129","cn":"amsterdam403"}],"ovpntcp":[{"ip":"143.244.41.137","cn":"amsterdam403"}],"ovpnudp":[{"ip":"143.244.41.145","cn":"amsterdam403"}],"wg":[{"ip":"84.247.116.221","cn":"amsterdam403"}]}},{"id":"us_minnesota-pf","name":"US Minnesota","country":"US","auto_region":true,"dns":"us-minnesota-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.86.150","cn":"minnesota401"}],"meta":[{"ip":"154.6.86.130","cn":"minnesota401"}],"ovpntcp":[{"ip":"154.6.86.145","cn":"minnesota401"}],"ovpnudp":[{"ip":"154.6.86.149","cn":"minnesota401"}],"wg":[{"ip":"154.6.86.131","cn":"minnesota401"}]}},{"id":"denmark","name":"DK Copenhagen","country":"DK","auto_region":true,"dns":"denmark.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"188.126.94.164","cn":"copenhagen404"}],"meta":[{"ip":"188.126.94.162","cn":"copenhagen404"}],"ovpntcp":[{"ip":"188.126.94.171","cn":"copenhagen404"}],"ovpnudp":[{"ip":"188.126.94.178","cn":"copenhagen404"}],"wg":[{"ip":"188.126.94.188","cn":"copenhagen404"}]}},{"id":"morocco","name":"Morocco","country":"MA","auto_region":true,"dns":"morocco.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"95.181.232.8","cn":"morocco403"}],"meta":[{"ip":"95.181.232.2","cn":"morocco403"}],"ovpntcp":[{"ip":"95.181.232.7","cn":"morocco403"}],"ovpnudp":[{"ip":"95.181.232.13","cn":"morocco403"}],"wg":[{"ip":"95.181.232.12","cn":"morocco403"}]}},{"id":"us-honolulu","name":"US Honolulu","country":"US","auto_region":true,"dns":"us-honolulu.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"149.57.29.25","cn":"honolulu401"}],"meta":[{"ip":"149.57.29.1","cn":"honolulu401"}],"ovpntcp":[{"ip":"149.57.29.28","cn":"honolulu401"}],"ovpnudp":[{"ip":"149.57.29.25","cn":"honolulu401"}],"wg":[{"ip":"149.57.29.29","cn":"honolulu401"}]}},{"id":"us_north_carolina-pf","name":"US North Carolina","country":"US","auto_region":true,"dns":"us-north-carolina-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.82.17","cn":"northcarolina401"}],"meta":[{"ip":"154.6.82.2","cn":"northcarolina401"}],"ovpntcp":[{"ip":"154.6.82.6","cn":"northcarolina401"}],"ovpnudp":[{"ip":"154.6.82.10","cn":"northcarolina401"}],"wg":[{"ip":"154.6.82.9","cn":"northcarolina401"}]}},{"id":"us_virginia-pf","name":"US Virginia","country":"US","auto_region":true,"dns":"us-virginia-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.83.135","cn":"virginia401"}],"meta":[{"ip":"154.6.83.130","cn":"virginia401"}],"ovpntcp":[{"ip":"154.6.83.148","cn":"virginia401"}],"ovpnudp":[{"ip":"154.6.83.134","cn":"virginia401"}],"wg":[{"ip":"154.6.83.144","cn":"virginia401"}]}},{"id":"bangladesh","name":"Bangladesh","country":"BD","auto_region":true,"dns":"bangladesh.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"64.64.112.131","cn":"bangladesh404"}],"meta":[{"ip":"64.64.112.128","cn":"bangladesh404"}],"ovpntcp":[{"ip":"64.64.112.155","cn":"bangladesh404"}],"ovpnudp":[{"ip":"64.64.112.146","cn":"bangladesh404"}],"wg":[{"ip":"64.64.112.151","cn":"bangladesh404"}]}},{"id":"us_las_vegas","name":"US Las Vegas","country":"US","auto_region":true,"dns":"us-lasvegas.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"154.16.105.169","cn":"lasvegas418"}],"meta":[{"ip":"154.16.105.7","cn":"lasvegas418"}],"ovpntcp":[{"ip":"154.16.105.189","cn":"lasvegas418"}],"ovpnudp":[{"ip":"154.16.105.183","cn":"lasvegas418"}],"wg":[{"ip":"154.16.105.184","cn":"lasvegas418"}]}},{"id":"mexico","name":"Mexico","country":"MX","auto_region":true,"dns":"mexico.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"77.81.142.116","cn":"mexico410"}],"meta":[{"ip":"77.81.142.105","cn":"mexico410"}],"ovpntcp":[{"ip":"77.81.142.108","cn":"mexico410"}],"ovpnudp":[{"ip":"77.81.142.109","cn":"mexico410"}],"wg":[{"ip":"77.81.142.115","cn":"mexico410"}]}},{"id":"hk","name":"Hong Kong","country":"HK","auto_region":true,"dns":"hk.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"86.107.104.245","cn":"hongkong404"}],"meta":[{"ip":"86.107.104.241","cn":"hongkong404"}],"ovpntcp":[{"ip":"86.107.104.251","cn":"hongkong404"}],"ovpnudp":[{"ip":"86.107.104.246","cn":"hongkong404"}],"wg":[{"ip":"86.107.104.245","cn":"hongkong404"}]}},{"id":"us_pennsylvania-pf","name":"US Pennsylvania","country":"US","auto_region":true,"dns":"us-pennsylvania-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.12.54","cn":"pennsylvania402"}],"meta":[{"ip":"154.6.12.28","cn":"pennsylvania402"}],"ovpntcp":[{"ip":"154.6.12.29","cn":"pennsylvania402"}],"ovpnudp":[{"ip":"154.6.12.29","cn":"pennsylvania402"}],"wg":[{"ip":"154.6.12.32","cn":"pennsylvania402"}]}},{"id":"us_connecticut-pf","name":"US Connecticut","country":"US","auto_region":true,"dns":"us-connecticut-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"173.239.232.30","cn":"connecticut403"}],"meta":[{"ip":"173.239.232.28","cn":"connecticut403"}],"ovpntcp":[{"ip":"173.239.232.53","cn":"connecticut403"}],"ovpnudp":[{"ip":"173.239.232.33","cn":"connecticut403"}],"wg":[{"ip":"173.239.232.42","cn":"connecticut403"}]}},{"id":"au_brisbane-pf","name":"AU Brisbane","country":"AU","auto_region":true,"dns":"au-brisbane-pf.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"223.252.34.36","cn":"brisbane401"}],"meta":[{"ip":"223.252.34.34","cn":"brisbane401"}],"ovpntcp":[{"ip":"223.252.34.51","cn":"brisbane401"}],"ovpnudp":[{"ip":"223.252.34.48","cn":"brisbane401"}],"wg":[{"ip":"223.252.34.50","cn":"brisbane401"}]}},{"id":"us_new_york_city","name":"US New York","country":"US","auto_region":true,"dns":"us-newyorkcity.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"191.96.227.133","cn":"newyork444"}],"meta":[{"ip":"191.96.227.5","cn":"newyork444"}],"ovpntcp":[{"ip":"191.96.227.148","cn":"newyork444"}],"ovpnudp":[{"ip":"191.96.227.156","cn":"newyork444"}],"wg":[{"ip":"191.96.227.149","cn":"newyork444"}]}},{"id":"kazakhstan","name":"Kazakhstan","country":"KZ","auto_region":true,"dns":"kazakhstan.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"62.133.47.7","cn":"kazakhstan403"}],"meta":[{"ip":"62.133.47.2","cn":"kazakhstan403"}],"ovpntcp":[{"ip":"62.133.47.6","cn":"kazakhstan403"}],"ovpnudp":[{"ip":"62.133.47.9","cn":"kazakhstan403"}],"wg":[{"ip":"62.133.47.11","cn":"kazakhstan403"}]}},{"id":"nz","name":"New Zealand","country":"NZ","auto_region":true,"dns":"nz.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"179.61.240.105","cn":"newzealand404"}],"meta":[{"ip":"202.60.86.2","cn":"newzealand404"}],"ovpntcp":[{"ip":"179.61.240.76","cn":"newzealand404"}],"ovpnudp":[{"ip":"179.61.240.96","cn":"newzealand404"}],"wg":[{"ip":"179.61.240.83","cn":"newzealand404"}]}},{"id":"us_indiana-pf","name":"US Indiana","country":"US","auto_region":true,"dns":"us-indiana-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.85.6","cn":"indiana401"}],"meta":[{"ip":"154.6.85.2","cn":"indiana401"}],"ovpntcp":[{"ip":"154.6.85.14","cn":"indiana401"}],"ovpnudp":[{"ip":"154.6.85.14","cn":"indiana401"}],"wg":[{"ip":"154.6.85.13","cn":"indiana401"}]}},{"id":"japan","name":"JP Tokyo","country":"JP","auto_region":true,"dns":"japan.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"154.47.20.163","cn":"tokyo402"}],"meta":[{"ip":"154.47.20.160","cn":"tokyo402"}],"ovpntcp":[{"ip":"154.47.20.172","cn":"tokyo402"}],"ovpnudp":[{"ip":"154.47.20.177","cn":"tokyo402"}],"wg":[{"ip":"154.47.20.175","cn":"tokyo402"}]}},{"id":"belgium","name":"Belgium","country":"BE","auto_region":true,"dns":"brussels.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"181.214.218.36","cn":"brussels418"}],"meta":[{"ip":"181.214.218.3","cn":"brussels418"}],"ovpntcp":[{"ip":"181.214.218.41","cn":"brussels418"}],"ovpnudp":[{"ip":"181.214.218.37","cn":"brussels418"}],"wg":[{"ip":"181.214.218.36","cn":"brussels418"}]}},{"id":"uy_uruguay-pf","name":"Uruguay","country":"UY","auto_region":true,"dns":"uy-uruguay-pf.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"84.247.101.25","cn":"uruguay401"}],"meta":[{"ip":"84.247.101.2","cn":"uruguay401"}],"ovpntcp":[{"ip":"84.247.101.28","cn":"uruguay401"}],"ovpnudp":[{"ip":"84.247.101.27","cn":"uruguay401"}],"wg":[{"ip":"84.247.101.14","cn":"uruguay401"}]}},{"id":"us_west_virginia-pf","name":"US West Virginia","country":"US","auto_region":true,"dns":"us-west-virginia-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.84.20","cn":"westvirginia401"}],"meta":[{"ip":"154.6.84.2","cn":"westvirginia401"}],"ovpntcp":[{"ip":"154.6.84.12","cn":"westvirginia401"}],"ovpnudp":[{"ip":"154.6.84.14","cn":"westvirginia401"}],"wg":[{"ip":"154.6.84.20","cn":"westvirginia401"}]}},{"id":"us_south_carolina-pf","name":"US South Carolina","country":"US","auto_region":true,"dns":"us-south-carolina-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.82.138","cn":"southcarolina401"}],"meta":[{"ip":"154.6.82.130","cn":"southcarolina401"}],"ovpntcp":[{"ip":"154.6.82.141","cn":"southcarolina401"}],"ovpnudp":[{"ip":"154.6.82.141","cn":"southcarolina401"}],"wg":[{"ip":"154.6.82.133","cn":"southcarolina401"}]}},{"id":"srilanka","name":"Sri Lanka","country":"LK","auto_region":true,"dns":"srilanka.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"95.181.239.3","cn":"srilanka403"}],"meta":[{"ip":"95.181.239.2","cn":"srilanka403"}],"ovpntcp":[{"ip":"95.181.239.3","cn":"srilanka403"}],"ovpnudp":[{"ip":"95.181.239.12","cn":"srilanka403"}],"wg":[{"ip":"95.181.239.11","cn":"srilanka403"}]}},{"id":"philippines","name":"Philippines","country":"PH","auto_region":true,"dns":"philippines.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"188.214.125.137","cn":"philippines401"}],"meta":[{"ip":"188.214.125.130","cn":"philippines401"}],"ovpntcp":[{"ip":"188.214.125.134","cn":"philippines401"}],"ovpnudp":[{"ip":"188.214.125.133","cn":"philippines401"}],"wg":[{"ip":"188.214.125.142","cn":"philippines401"}]}},{"id":"fi","name":"FI Helsinki","country":"FI","auto_region":true,"dns":"fi.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"188.126.89.46","cn":"helsinki402"}],"meta":[{"ip":"188.126.89.34","cn":"helsinki402"}],"ovpntcp":[{"ip":"188.126.89.56","cn":"helsinki402"}],"ovpnudp":[{"ip":"188.126.89.60","cn":"helsinki402"}],"wg":[{"ip":"188.126.89.38","cn":"helsinki402"}]}},{"id":"us_oregon-pf","name":"US Oregon","country":"US","auto_region":true,"dns":"us-oregon-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.92.11","cn":"oregon401"}],"meta":[{"ip":"154.6.92.2","cn":"oregon401"}],"ovpntcp":[{"ip":"154.6.92.22","cn":"oregon401"}],"ovpnudp":[{"ip":"154.6.92.5","cn":"oregon401"}],"wg":[{"ip":"154.6.92.27","cn":"oregon401"}]}},{"id":"kualalumpur","name":"Malaysia","country":"MY","auto_region":true,"dns":"kualalumpur.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"146.70.15.22","cn":"malaysia401"}],"meta":[{"ip":"146.70.15.17","cn":"malaysia401"}],"ovpntcp":[{"ip":"146.70.15.22","cn":"malaysia401"}],"ovpnudp":[{"ip":"146.70.15.27","cn":"malaysia401"}],"wg":[{"ip":"146.70.15.33","cn":"malaysia401"}]}},{"id":"macau","name":"Macao","country":"MO","auto_region":true,"dns":"macau.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"84.252.92.20","cn":"macau404"}],"meta":[{"ip":"84.252.92.16","cn":"macau404"}],"ovpntcp":[{"ip":"84.252.92.26","cn":"macau404"}],"ovpnudp":[{"ip":"84.252.92.26","cn":"macau404"}],"wg":[{"ip":"84.252.92.27","cn":"macau404"}]}},{"id":"rs","name":"Serbia","country":"RS","auto_region":true,"dns":"rs.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"37.46.115.30","cn":"belgrade402"}],"meta":[{"ip":"37.46.115.15","cn":"belgrade402"}],"ovpntcp":[{"ip":"37.46.115.18","cn":"belgrade402"}],"ovpnudp":[{"ip":"37.46.115.23","cn":"belgrade402"}],"wg":[{"ip":"37.46.115.30","cn":"belgrade402"}]}},{"id":"spain","name":"ES Madrid","country":"ES","auto_region":true,"dns":"spain.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"212.102.49.89","cn":"madrid401"}],"meta":[{"ip":"195.181.167.33","cn":"madrid401"}],"ovpntcp":[{"ip":"212.102.49.67","cn":"madrid401"}],"ovpnudp":[{"ip":"195.181.167.35","cn":"madrid401"}],"wg":[{"ip":"212.102.49.65","cn":"madrid401"}]}},{"id":"ec_ecuador-pf","name":"Ecuador","country":"EC","auto_region":true,"dns":"ec-ecuador-pf.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"84.247.93.11","cn":"ecuador401"}],"meta":[{"ip":"84.247.93.2","cn":"ecuador401"}],"ovpntcp":[{"ip":"84.247.93.10","cn":"ecuador401"}],"ovpnudp":[{"ip":"84.247.93.15","cn":"ecuador401"}],"wg":[{"ip":"84.247.93.18","cn":"ecuador401"}]}},{"id":"sk","name":"Slovakia","country":"SK","auto_region":true,"dns":"sk.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"149.102.232.3","cn":"bratislava403"}],"meta":[{"ip":"149.102.232.1","cn":"bratislava403"}],"ovpntcp":[{"ip":"149.102.232.15","cn":"bratislava403"}],"ovpnudp":[{"ip":"149.102.232.26","cn":"bratislava403"}],"wg":[{"ip":"149.102.232.14","cn":"bratislava403"}]}},{"id":"us_iowa-pf","name":"US Iowa","country":"US","auto_region":true,"dns":"us-iowa-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.85.145","cn":"iowa401"}],"meta":[{"ip":"154.6.85.130","cn":"iowa401"}],"ovpntcp":[{"ip":"154.6.85.136","cn":"iowa401"}],"ovpnudp":[{"ip":"154.6.85.143","cn":"iowa401"}],"wg":[{"ip":"154.6.85.152","cn":"iowa401"}]}},{"id":"us_alabama-pf","name":"US Alabama","country":"US","auto_region":true,"dns":"us-alabama-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.80.20","cn":"alabama401"}],"meta":[{"ip":"154.6.80.2","cn":"alabama401"}],"ovpntcp":[{"ip":"154.6.80.12","cn":"alabama401"}],"ovpnudp":[{"ip":"154.6.80.5","cn":"alabama401"}],"wg":[{"ip":"154.6.80.4","cn":"alabama401"}]}},{"id":"us_new_mexico-pf","name":"US New Mexico","country":"US","auto_region":true,"dns":"us-new-mexico-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.90.28","cn":"newmexico401"}],"meta":[{"ip":"154.6.90.2","cn":"newmexico401"}],"ovpntcp":[{"ip":"154.6.90.22","cn":"newmexico401"}],"ovpnudp":[{"ip":"154.6.90.15","cn":"newmexico401"}],"wg":[{"ip":"154.6.90.29","cn":"newmexico401"}]}},{"id":"hungary","name":"Hungary","country":"HU","auto_region":true,"dns":"hungary.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"217.138.192.220","cn":"budapest401"}],"meta":[{"ip":"185.189.114.102","cn":"budapest401"}],"ovpntcp":[{"ip":"217.138.192.218","cn":"budapest401"}],"ovpnudp":[{"ip":"217.138.192.220","cn":"budapest401"}],"wg":[{"ip":"217.138.192.220","cn":"budapest401"}]}},{"id":"pt","name":"Portugal","country":"PT","auto_region":true,"dns":"pt.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"146.70.59.10","cn":"lisbon405"}],"meta":[{"ip":"146.70.59.2","cn":"lisbon405"}],"ovpntcp":[{"ip":"146.70.59.12","cn":"lisbon405"}],"ovpnudp":[{"ip":"146.70.59.10","cn":"lisbon405"}],"wg":[{"ip":"146.70.59.25","cn":"lisbon405"}]}},{"id":"liechtenstein","name":"Liechtenstein","country":"LI","auto_region":true,"dns":"liechtenstein.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"91.90.122.19","cn":"liechtenstein403"}],"meta":[{"ip":"91.90.122.2","cn":"liechtenstein403"}],"ovpntcp":[{"ip":"91.90.122.14","cn":"liechtenstein403"}],"ovpnudp":[{"ip":"91.90.122.6","cn":"liechtenstein403"}],"wg":[{"ip":"91.90.122.13","cn":"liechtenstein403"}]}},{"id":"jakarta","name":"Indonesia","country":"ID","auto_region":true,"dns":"jakarta.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"192.142.226.150","cn":"indonesia403"}],"meta":[{"ip":"84.17.39.187","cn":"indonesia403"}],"ovpntcp":[{"ip":"192.142.226.154","cn":"indonesia403"}],"ovpnudp":[{"ip":"192.142.226.147","cn":"indonesia403"}],"wg":[{"ip":"192.142.226.149","cn":"indonesia403"}]}},{"id":"man","name":"Isle of Man","country":"IM","auto_region":true,"dns":"man.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"91.90.124.23","cn":"douglas404"}],"meta":[{"ip":"91.90.124.20","cn":"douglas404"}],"ovpntcp":[{"ip":"91.90.124.25","cn":"douglas404"}],"ovpnudp":[{"ip":"91.90.124.32","cn":"douglas404"}],"wg":[{"ip":"91.90.124.31","cn":"douglas404"}]}},{"id":"us_kentucky-pf","name":"US Kentucky","country":"US","auto_region":true,"dns":"us-kentucky-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.80.135","cn":"kentucky401"}],"meta":[{"ip":"154.6.80.130","cn":"kentucky401"}],"ovpntcp":[{"ip":"154.6.80.150","cn":"kentucky401"}],"ovpnudp":[{"ip":"154.6.80.145","cn":"kentucky401"}],"wg":[{"ip":"154.6.80.143","cn":"kentucky401"}]}},{"id":"italy","name":"IT Milano","country":"IT","auto_region":true,"dns":"italy.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"156.146.41.21","cn":"milano402"}],"meta":[{"ip":"156.146.41.1","cn":"milano402"}],"ovpntcp":[{"ip":"156.146.41.21","cn":"milano402"}],"ovpnudp":[{"ip":"156.146.41.6","cn":"milano402"}],"wg":[{"ip":"156.146.41.23","cn":"milano402"}]}},{"id":"egypt","name":"Egypt","country":"EG","auto_region":true,"dns":"egypt.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"188.214.122.121","cn":"cairo402"}],"meta":[{"ip":"188.214.122.114","cn":"cairo402"}],"ovpntcp":[{"ip":"188.214.122.118","cn":"cairo402"}],"ovpnudp":[{"ip":"188.214.122.123","cn":"cairo402"}],"wg":[{"ip":"188.214.122.116","cn":"cairo402"}]}},{"id":"gr","name":"Greece","country":"GR","auto_region":true,"dns":"gr.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"195.146.6.59","cn":"athens402"}],"meta":[{"ip":"195.146.6.50","cn":"athens402"}],"ovpntcp":[{"ip":"195.146.6.55","cn":"athens402"}],"ovpnudp":[{"ip":"195.146.6.63","cn":"athens402"}],"wg":[{"ip":"195.146.6.64","cn":"athens402"}]}},{"id":"sg","name":"Singapore","country":"SG","auto_region":true,"dns":"sg.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"156.146.57.44","cn":"singapore403"}],"meta":[{"ip":"156.146.57.38","cn":"singapore403"}],"ovpntcp":[{"ip":"156.146.57.50","cn":"singapore403"}],"ovpnudp":[{"ip":"156.146.57.52","cn":"singapore403"}],"wg":[{"ip":"156.146.57.52","cn":"singapore403"}]}},{"id":"austria","name":"Austria","country":"AT","auto_region":true,"dns":"austria.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"156.146.60.132","cn":"vienna401"}],"meta":[{"ip":"156.146.60.129","cn":"vienna401"}],"ovpntcp":[{"ip":"156.146.60.133","cn":"vienna401"}],"ovpnudp":[{"ip":"156.146.60.132","cn":"vienna401"}],"wg":[{"ip":"156.146.60.132","cn":"vienna401"}]}},{"id":"us-saltlakecity","name":"US Salt Lake City","country":"US","auto_region":true,"dns":"us-saltlakecity.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"149.57.29.170","cn":"saltlake402"}],"meta":[{"ip":"149.57.29.160","cn":"saltlake402"}],"ovpntcp":[{"ip":"149.57.29.186","cn":"saltlake402"}],"ovpnudp":[{"ip":"149.57.29.173","cn":"saltlake402"}],"wg":[{"ip":"149.57.29.171","cn":"saltlake402"}]}},{"id":"us-wilmington","name":"US Wilmington","country":"US","auto_region":true,"dns":"us-wilmington.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"149.57.16.184","cn":"wilmington402"}],"meta":[{"ip":"149.57.16.161","cn":"wilmington402"}],"ovpntcp":[{"ip":"149.57.16.162","cn":"wilmington402"}],"ovpnudp":[{"ip":"149.57.16.190","cn":"wilmington402"}],"wg":[{"ip":"149.57.16.177","cn":"wilmington402"}]}},{"id":"santiago","name":"Chile","country":"CL","auto_region":true,"dns":"santiago.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"146.70.11.39","cn":"chile402"}],"meta":[{"ip":"146.70.11.28","cn":"chile402"}],"ovpntcp":[{"ip":"146.70.11.33","cn":"chile402"}],"ovpnudp":[{"ip":"146.70.11.37","cn":"chile402"}],"wg":[{"ip":"146.70.11.39","cn":"chile402"}]}},{"id":"us_oklahoma-pf","name":"US Oklahoma","country":"US","auto_region":true,"dns":"us-oklahoma-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.90.152","cn":"oklahoma401"}],"meta":[{"ip":"154.6.90.130","cn":"oklahoma401"}],"ovpntcp":[{"ip":"154.6.90.139","cn":"oklahoma401"}],"ovpnudp":[{"ip":"154.6.90.149","cn":"oklahoma401"}],"wg":[{"ip":"154.6.90.150","cn":"oklahoma401"}]}},{"id":"us_mississippi-pf","name":"US Mississippi","country":"US","auto_region":true,"dns":"us-mississippi-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.89.137","cn":"mississippi401"}],"meta":[{"ip":"154.6.89.130","cn":"mississippi401"}],"ovpntcp":[{"ip":"154.6.89.150","cn":"mississippi401"}],"ovpnudp":[{"ip":"154.6.89.153","cn":"mississippi401"}],"wg":[{"ip":"154.6.89.139","cn":"mississippi401"}]}},{"id":"poland","name":"Poland","country":"PL","auto_region":true,"dns":"poland.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"138.199.59.56","cn":"warsaw410"}],"meta":[{"ip":"138.199.59.33","cn":"warsaw410"}],"ovpntcp":[{"ip":"138.199.59.54","cn":"warsaw410"}],"ovpnudp":[{"ip":"138.199.59.57","cn":"warsaw410"}],"wg":[{"ip":"138.199.59.40","cn":"warsaw410"}]}},{"id":"china","name":"China","country":"CN","auto_region":true,"dns":"china.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"188.241.80.46","cn":"china407"}],"meta":[{"ip":"188.241.80.43","cn":"china407"}],"ovpntcp":[{"ip":"188.241.80.49","cn":"china407"}],"ovpnudp":[{"ip":"188.241.80.48","cn":"china407"}],"wg":[{"ip":"188.241.80.45","cn":"china407"}]}},{"id":"kr_south_korea-pf","name":"South Korea","country":"KR","auto_region":true,"dns":"kr-south-korea-pf.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"84.247.102.7","cn":"seoul401"}],"meta":[{"ip":"84.247.102.2","cn":"seoul401"}],"ovpntcp":[{"ip":"84.247.102.12","cn":"seoul401"}],"ovpnudp":[{"ip":"84.247.102.7","cn":"seoul401"}],"wg":[{"ip":"84.247.102.9","cn":"seoul401"}]}},{"id":"us_rhode_island-pf","name":"US Rhode Island","country":"US","auto_region":true,"dns":"us-rhode-island-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.94.10","cn":"rhodeisland401"}],"meta":[{"ip":"154.6.94.2","cn":"rhodeisland401"}],"ovpntcp":[{"ip":"154.6.94.11","cn":"rhodeisland401"}],"ovpnudp":[{"ip":"154.6.94.15","cn":"rhodeisland401"}],"wg":[{"ip":"154.6.94.13","cn":"rhodeisland401"}]}},{"id":"us_missouri-pf","name":"US Missouri","country":"US","auto_region":true,"dns":"us-missouri-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.87.23","cn":"missouri401"}],"meta":[{"ip":"154.6.87.2","cn":"missouri401"}],"ovpntcp":[{"ip":"154.6.87.6","cn":"missouri401"}],"ovpnudp":[{"ip":"154.6.87.24","cn":"missouri401"}],"wg":[{"ip":"154.6.87.10","cn":"missouri401"}]}},{"id":"us_silicon_valley","name":"US Silicon Valley","country":"US","auto_region":true,"dns":"us-siliconvalley.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"191.96.255.39","cn":"siliconvalley414"}],"meta":[{"ip":"191.96.255.3","cn":"siliconvalley414"}],"ovpntcp":[{"ip":"191.96.255.37","cn":"siliconvalley414"}],"ovpnudp":[{"ip":"191.96.255.15","cn":"siliconvalley414"}],"wg":[{"ip":"191.96.255.26","cn":"siliconvalley414"}]}},{"id":"aus","name":"AU Sydney","country":"AU","auto_region":true,"dns":"au-sydney.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"154.16.81.187","cn":"sydney434"}],"meta":[{"ip":"154.16.81.7","cn":"sydney434"}],"ovpntcp":[{"ip":"154.16.81.172","cn":"sydney434"}],"ovpnudp":[{"ip":"154.16.81.166","cn":"sydney434"}],"wg":[{"ip":"154.16.81.165","cn":"sydney434"}]}},{"id":"ireland","name":"Ireland","country":"IE","auto_region":true,"dns":"ireland.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"149.34.242.140","cn":"dublin421"}],"meta":[{"ip":"149.34.242.129","cn":"dublin421"}],"ovpntcp":[{"ip":"149.34.242.141","cn":"dublin421"}],"ovpnudp":[{"ip":"149.34.242.155","cn":"dublin421"}],"wg":[{"ip":"149.34.242.137","cn":"dublin421"}]}},{"id":"sofia","name":"Bulgaria","country":"BG","auto_region":true,"dns":"sofia.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"94.156.14.10","cn":"sofia405"}],"meta":[{"ip":"94.156.14.1","cn":"sofia405"}],"ovpntcp":[{"ip":"94.156.14.6","cn":"sofia405"}],"ovpnudp":[{"ip":"94.156.14.15","cn":"sofia405"}],"wg":[{"ip":"94.156.14.19","cn":"sofia405"}]}},{"id":"mk","name":"North Macedonia","country":"MK","auto_region":true,"dns":"mk.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"185.225.28.235","cn":"macedonia401"}],"meta":[{"ip":"185.225.28.226","cn":"macedonia401"}],"ovpntcp":[{"ip":"185.225.28.231","cn":"macedonia401"}],"ovpnudp":[{"ip":"185.225.28.230","cn":"macedonia401"}],"wg":[{"ip":"185.225.28.233","cn":"macedonia401"}]}},{"id":"italy_2","name":"IT Streaming Optimized","country":"IT","auto_region":false,"dns":"italy-2.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"138.199.54.41","cn":"milano405"}],"meta":[{"ip":"138.199.54.33","cn":"milano405"}],"ovpntcp":[{"ip":"138.199.54.44","cn":"milano405"}],"ovpnudp":[{"ip":"138.199.54.46","cn":"milano405"}],"wg":[{"ip":"138.199.54.45","cn":"milano405"}]}},{"id":"de-frankfurt","name":"DE Frankfurt","country":"DE","auto_region":true,"dns":"de-frankfurt.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"45.88.97.36","cn":"frankfurt414"}],"meta":[{"ip":"45.88.97.2","cn":"frankfurt414"}],"ovpntcp":[{"ip":"45.88.97.50","cn":"frankfurt414"}],"ovpnudp":[{"ip":"45.88.97.25","cn":"frankfurt414"}],"wg":[{"ip":"45.88.97.25","cn":"frankfurt414"}]}},{"id":"us-streaming","name":"US East Streaming Optimized","country":"US","auto_region":false,"dns":"us-streaming.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"102.165.16.38","cn":"newjersey425"}],"meta":[{"ip":"102.165.16.2","cn":"newjersey425"}],"ovpntcp":[{"ip":"102.165.16.19","cn":"newjersey425"}],"ovpnudp":[{"ip":"102.165.16.36","cn":"newjersey425"}],"wg":[{"ip":"102.165.16.17","cn":"newjersey425"}]}},{"id":"sweden_2","name":"SE Streaming Optimized","country":"SE","auto_region":false,"dns":"sweden-2.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"46.246.3.223","cn":"stockholm406"}],"meta":[{"ip":"46.246.3.220","cn":"stockholm406"}],"ovpntcp":[{"ip":"46.246.3.244","cn":"stockholm406"}],"ovpnudp":[{"ip":"46.246.3.237","cn":"stockholm406"}],"wg":[{"ip":"46.246.3.243","cn":"stockholm406"}]}},{"id":"tr","name":"Turkey","country":"TR","auto_region":true,"dns":"tr.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"188.213.34.140","cn":"istanbul404"}],"meta":[{"ip":"188.213.34.138","cn":"istanbul404"}],"ovpntcp":[{"ip":"188.213.34.140","cn":"istanbul404"}],"ovpnudp":[{"ip":"188.213.34.140","cn":"istanbul404"}],"wg":[{"ip":"188.213.34.139","cn":"istanbul404"}]}},{"id":"us_california","name":"US California","country":"US","auto_region":true,"dns":"us-california.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"191.96.106.76","cn":"losangeles433"}],"meta":[{"ip":"191.96.106.4","cn":"losangeles433"}],"ovpntcp":[{"ip":"191.96.106.95","cn":"losangeles433"}],"ovpnudp":[{"ip":"191.96.106.84","cn":"losangeles433"}],"wg":[{"ip":"191.96.106.89","cn":"losangeles433"}]}},{"id":"us_chicago","name":"US Chicago","country":"US","auto_region":true,"dns":"us-chicago.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"181.214.166.108","cn":"chicago418"}],"meta":[{"ip":"181.214.166.98","cn":"chicago418"}],"ovpntcp":[{"ip":"181.214.166.136","cn":"chicago418"}],"ovpnudp":[{"ip":"181.214.166.140","cn":"chicago418"}],"wg":[{"ip":"181.214.166.132","cn":"chicago418"}]}},{"id":"us_nebraska-pf","name":"US Nebraska","country":"US","auto_region":true,"dns":"us-nebraska-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.95.131","cn":"nebraska401"}],"meta":[{"ip":"154.6.95.130","cn":"nebraska401"}],"ovpntcp":[{"ip":"154.6.95.139","cn":"nebraska401"}],"ovpnudp":[{"ip":"154.6.95.136","cn":"nebraska401"}],"wg":[{"ip":"154.6.95.146","cn":"nebraska401"}]}},{"id":"monaco","name":"Monaco","country":"MC","auto_region":true,"dns":"monaco.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"95.181.233.18","cn":"monaco404"}],"meta":[{"ip":"95.181.233.14","cn":"monaco404"}],"ovpntcp":[{"ip":"95.181.233.15","cn":"monaco404"}],"ovpnudp":[{"ip":"95.181.233.18","cn":"monaco404"}],"wg":[{"ip":"95.181.233.19","cn":"monaco404"}]}},{"id":"np_nepal-pf","name":"Nepal","country":"NP","auto_region":true,"dns":"np-nepal-pf.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"84.247.97.6","cn":"kathmandu401"}],"meta":[{"ip":"84.247.97.2","cn":"kathmandu401"}],"ovpntcp":[{"ip":"84.247.97.8","cn":"kathmandu401"}],"ovpnudp":[{"ip":"84.247.97.4","cn":"kathmandu401"}],"wg":[{"ip":"84.247.97.11","cn":"kathmandu401"}]}},{"id":"swiss","name":"Switzerland","country":"CH","auto_region":true,"dns":"swiss.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"212.102.36.9","cn":"zurich405"}],"meta":[{"ip":"212.102.36.1","cn":"zurich405"}],"ovpntcp":[{"ip":"212.102.36.15","cn":"zurich405"}],"ovpnudp":[{"ip":"212.102.36.19","cn":"zurich405"}],"wg":[{"ip":"212.102.36.14","cn":"zurich405"}]}},{"id":"japan_2","name":"JP Streaming Optimized","country":"JP","auto_region":false,"dns":"japan-2.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"154.47.20.135","cn":"tokyo401"}],"meta":[{"ip":"154.47.20.129","cn":"tokyo401"}],"ovpntcp":[{"ip":"154.47.20.140","cn":"tokyo401"}],"ovpnudp":[{"ip":"154.47.20.138","cn":"tokyo401"}],"wg":[{"ip":"154.47.20.151","cn":"tokyo401"}]}},{"id":"md","name":"Moldova","country":"MD","auto_region":true,"dns":"md.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"178.175.128.38","cn":"chisinau402"}],"meta":[{"ip":"178.175.128.34","cn":"chisinau402"}],"ovpntcp":[{"ip":"178.175.128.37","cn":"chisinau402"}],"ovpnudp":[{"ip":"178.175.128.41","cn":"chisinau402"}],"wg":[{"ip":"178.175.128.39","cn":"chisinau402"}]}},{"id":"us-streaming-2","name":"US West Streaming Optimized","country":"US","auto_region":false,"dns":"us-streaming-2.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"102.129.252.109","cn":"siliconvalley410"}],"meta":[{"ip":"102.129.252.97","cn":"siliconvalley410"}],"ovpntcp":[{"ip":"102.129.252.121","cn":"siliconvalley410"}],"ovpnudp":[{"ip":"102.129.252.101","cn":"siliconvalley410"}],"wg":[{"ip":"102.129.252.120","cn":"siliconvalley410"}]}},{"id":"sweden","name":"SE Stockholm","country":"SE","auto_region":true,"dns":"sweden.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"46.246.8.142","cn":"stockholm404"}],"meta":[{"ip":"46.246.3.106","cn":"stockholm404"}],"ovpntcp":[{"ip":"46.246.8.111","cn":"stockholm404"}],"ovpnudp":[{"ip":"46.246.8.135","cn":"stockholm404"}],"wg":[{"ip":"46.246.8.145","cn":"stockholm404"}]}},{"id":"sanjose","name":"Costa Rica","country":"CR","auto_region":true,"dns":"sanjose.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"146.70.10.34","cn":"costarica402"}],"meta":[{"ip":"146.70.10.28","cn":"costarica402"}],"ovpntcp":[{"ip":"146.70.10.38","cn":"costarica402"}],"ovpnudp":[{"ip":"146.70.10.37","cn":"costarica402"}],"wg":[{"ip":"146.70.10.33","cn":"costarica402"}]}},{"id":"us_louisiana-pf","name":"US Louisiana","country":"US","auto_region":true,"dns":"us-louisiana-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.81.155","cn":"louisiana401"}],"meta":[{"ip":"154.6.81.130","cn":"louisiana401"}],"ovpntcp":[{"ip":"154.6.81.151","cn":"louisiana401"}],"ovpnudp":[{"ip":"154.6.81.131","cn":"louisiana401"}],"wg":[{"ip":"154.6.81.141","cn":"louisiana401"}]}},{"id":"lv","name":"Latvia","country":"LV","auto_region":true,"dns":"lv.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"196.196.53.132","cn":"riga408"}],"meta":[{"ip":"196.196.53.130","cn":"riga408"}],"ovpntcp":[{"ip":"196.196.53.131","cn":"riga408"}],"ovpnudp":[{"ip":"196.196.53.142","cn":"riga408"}],"wg":[{"ip":"196.196.53.131","cn":"riga408"}]}},{"id":"ca_ontario","name":"CA Ontario","country":"CA","auto_region":true,"dns":"ca-ontario.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"172.83.47.149","cn":"ontario402"}],"meta":[{"ip":"172.83.47.135","cn":"ontario402"}],"ovpntcp":[{"ip":"172.83.47.168","cn":"ontario402"}],"ovpnudp":[{"ip":"172.83.47.163","cn":"ontario402"}],"wg":[{"ip":"172.83.47.139","cn":"ontario402"}]}},{"id":"israel","name":"Israel","country":"IL","auto_region":true,"dns":"israel.privacy.network","port_forward":true,"geo":false,"servers":{}},{"id":"es-valencia","name":"ES Valencia","country":"ES","auto_region":true,"dns":"es-valencia.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"196.245.54.172","cn":"valencia403"}],"meta":[{"ip":"196.245.54.160","cn":"valencia403"}],"ovpntcp":[{"ip":"196.245.54.168","cn":"valencia403"}],"ovpnudp":[{"ip":"196.245.54.171","cn":"valencia403"}],"wg":[{"ip":"196.245.54.166","cn":"valencia403"}]}},{"id":"us_wyoming-pf","name":"US Wyoming","country":"US","auto_region":true,"dns":"us-wyoming-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.93.21","cn":"wyoming401"}],"meta":[{"ip":"154.6.93.2","cn":"wyoming401"}],"ovpntcp":[{"ip":"154.6.93.14","cn":"wyoming401"}],"ovpnudp":[{"ip":"154.6.93.30","cn":"wyoming401"}],"wg":[{"ip":"154.6.93.20","cn":"wyoming401"}]}},{"id":"uk_2","name":"UK Streaming Optimized","country":"GB","auto_region":false,"dns":"uk-2.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"138.199.28.66","cn":"london446"}],"meta":[{"ip":"138.199.30.219","cn":"london446"}],"ovpntcp":[{"ip":"138.199.28.7","cn":"london446"}],"ovpnudp":[{"ip":"138.199.28.7","cn":"london446"}],"wg":[{"ip":"138.199.28.7","cn":"london446"}]}},{"id":"us_massachusetts-pf","name":"US Massachusetts","country":"US","auto_region":true,"dns":"us-massachusetts-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"149.40.50.46","cn":"massachusetts404"}],"meta":[{"ip":"149.40.50.33","cn":"massachusetts404"}],"ovpntcp":[{"ip":"149.40.50.56","cn":"massachusetts404"}],"ovpnudp":[{"ip":"149.40.50.39","cn":"massachusetts404"}],"wg":[{"ip":"149.40.50.56","cn":"massachusetts404"}]}},{"id":"bahamas","name":"Bahamas","country":"BS","auto_region":true,"dns":"bahamas.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"95.181.238.30","cn":"bahamas405"}],"meta":[{"ip":"95.181.238.26","cn":"bahamas405"}],"ovpntcp":[{"ip":"95.181.238.31","cn":"bahamas405"}],"ovpnudp":[{"ip":"95.181.238.30","cn":"bahamas405"}],"wg":[{"ip":"95.181.238.37","cn":"bahamas405"}]}},{"id":"fi_2","name":"FI Streaming Optimized","country":"FI","auto_region":false,"dns":"fi-2.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"188.126.89.7","cn":"helsinki401"}],"meta":[{"ip":"188.126.89.2","cn":"helsinki401"}],"ovpntcp":[{"ip":"188.126.89.21","cn":"helsinki401"}],"ovpnudp":[{"ip":"188.126.89.9","cn":"helsinki401"}],"wg":[{"ip":"188.126.89.12","cn":"helsinki401"}]}},{"id":"us_idaho-pf","name":"US Idaho","country":"US","auto_region":true,"dns":"us-idaho-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.95.28","cn":"idaho401"}],"meta":[{"ip":"154.6.95.2","cn":"idaho401"}],"ovpntcp":[{"ip":"154.6.95.27","cn":"idaho401"}],"ovpnudp":[{"ip":"154.6.95.12","cn":"idaho401"}],"wg":[{"ip":"154.6.95.13","cn":"idaho401"}]}},{"id":"us-baltimore","name":"US Baltimore","country":"US","auto_region":true,"dns":"us-baltimore.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"149.57.16.52","cn":"baltimore402"}],"meta":[{"ip":"149.57.16.33","cn":"baltimore402"}],"ovpntcp":[{"ip":"149.57.16.37","cn":"baltimore402"}],"ovpnudp":[{"ip":"149.57.16.35","cn":"baltimore402"}],"wg":[{"ip":"149.57.16.53","cn":"baltimore402"}]}},{"id":"us-newjersey","name":"US East","country":"US","auto_region":true,"dns":"us-newjersey.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"84.247.119.15","cn":"newjersey418"}],"meta":[{"ip":"37.19.197.189","cn":"newjersey418"}],"ovpntcp":[{"ip":"37.19.197.193","cn":"newjersey418"}],"ovpnudp":[{"ip":"84.247.119.29","cn":"newjersey418"}],"wg":[{"ip":"84.247.119.13","cn":"newjersey418"}]}},{"id":"uk","name":"UK London","country":"GB","auto_region":true,"dns":"uk-london.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"84.247.114.113","cn":"london411"}],"meta":[{"ip":"138.199.28.246","cn":"london411"}],"ovpntcp":[{"ip":"212.102.52.82","cn":"london411"}],"ovpnudp":[{"ip":"212.102.52.78","cn":"london411"}],"wg":[{"ip":"84.247.114.120","cn":"london411"}]}},{"id":"us_ohio-pf","name":"US Ohio","country":"US","auto_region":true,"dns":"us-ohio-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.88.147","cn":"ohio401"}],"meta":[{"ip":"154.6.88.130","cn":"ohio401"}],"ovpntcp":[{"ip":"154.6.88.146","cn":"ohio401"}],"ovpnudp":[{"ip":"154.6.88.147","cn":"ohio401"}],"wg":[{"ip":"154.6.88.133","cn":"ohio401"}]}},{"id":"us_south_dakota-pf","name":"US South Dakota","country":"US","auto_region":true,"dns":"us-south-dakota-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.92.135","cn":"southdakota401"}],"meta":[{"ip":"154.6.92.130","cn":"southdakota401"}],"ovpntcp":[{"ip":"154.6.92.149","cn":"southdakota401"}],"ovpnudp":[{"ip":"154.6.92.153","cn":"southdakota401"}],"wg":[{"ip":"154.6.92.153","cn":"southdakota401"}]}},{"id":"no","name":"Norway","country":"NO","auto_region":true,"dns":"no.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"46.246.122.189","cn":"oslo404"}],"meta":[{"ip":"46.246.122.162","cn":"oslo404"}],"ovpntcp":[{"ip":"46.246.122.174","cn":"oslo404"}],"ovpnudp":[{"ip":"46.246.122.178","cn":"oslo404"}],"wg":[{"ip":"46.246.122.178","cn":"oslo404"}]}},{"id":"cyprus","name":"Cyprus","country":"CY","auto_region":true,"dns":"cyprus.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"185.253.162.9","cn":"cyprus403"}],"meta":[{"ip":"185.253.162.2","cn":"cyprus403"}],"ovpntcp":[{"ip":"185.253.162.3","cn":"cyprus403"}],"ovpnudp":[{"ip":"185.253.162.7","cn":"cyprus403"}],"wg":[{"ip":"185.253.162.12","cn":"cyprus403"}]}},{"id":"france","name":"France","country":"FR","auto_region":true,"dns":"france.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"191.101.31.69","cn":"paris412"}],"meta":[{"ip":"191.101.31.3","cn":"paris412"}],"ovpntcp":[{"ip":"191.101.31.53","cn":"paris412"}],"ovpnudp":[{"ip":"191.101.31.42","cn":"paris412"}],"wg":[{"ip":"191.101.31.63","cn":"paris412"}]}},{"id":"aus_melbourne","name":"AU Melbourne","country":"AU","auto_region":true,"dns":"aus-melbourne.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"154.6.151.61","cn":"melbourne429"}],"meta":[{"ip":"154.6.151.3","cn":"melbourne429"}],"ovpntcp":[{"ip":"154.6.151.41","cn":"melbourne429"}],"ovpnudp":[{"ip":"154.6.151.69","cn":"melbourne429"}],"wg":[{"ip":"154.6.151.44","cn":"melbourne429"}]}},{"id":"slovenia","name":"Slovenia","country":"SI","auto_region":true,"dns":"slovenia.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"195.80.150.190","cn":"slovenia401"}],"meta":[{"ip":"195.80.150.178","cn":"slovenia401"}],"ovpntcp":[{"ip":"195.80.150.180","cn":"slovenia401"}],"ovpnudp":[{"ip":"195.80.150.182","cn":"slovenia401"}],"wg":[{"ip":"195.80.150.182","cn":"slovenia401"}]}},{"id":"saudiarabia","name":"Saudi Arabia","country":"SA","auto_region":true,"dns":"saudiarabia.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"95.181.235.151","cn":"saudiarabia404"}],"meta":[{"ip":"95.181.235.145","cn":"saudiarabia404"}],"ovpntcp":[{"ip":"95.181.235.147","cn":"saudiarabia404"}],"ovpnudp":[{"ip":"95.181.235.149","cn":"saudiarabia404"}],"wg":[{"ip":"95.181.235.147","cn":"saudiarabia404"}]}},{"id":"ar","name":"Argentina","country":"AR","auto_region":true,"dns":"ar.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"146.70.38.78","cn":"buenosaires409"}],"meta":[{"ip":"146.70.38.75","cn":"buenosaires409"}],"ovpntcp":[{"ip":"146.70.38.85","cn":"buenosaires409"}],"ovpnudp":[{"ip":"146.70.38.86","cn":"buenosaires409"}],"wg":[{"ip":"146.70.38.78","cn":"buenosaires409"}]}},{"id":"czech","name":"Czech Republic","country":"CZ","auto_region":true,"dns":"czech.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"212.102.39.66","cn":"prague403"}],"meta":[{"ip":"212.102.39.65","cn":"prague403"}],"ovpntcp":[{"ip":"212.102.39.213","cn":"prague403"}],"ovpnudp":[{"ip":"212.102.39.195","cn":"prague403"}],"wg":[{"ip":"212.102.39.197","cn":"prague403"}]}},{"id":"zagreb","name":"Croatia","country":"HR","auto_region":true,"dns":"zagreb.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"149.102.247.236","cn":"zagreb404"}],"meta":[{"ip":"149.102.247.225","cn":"zagreb404"}],"ovpntcp":[{"ip":"149.102.247.249","cn":"zagreb404"}],"ovpnudp":[{"ip":"149.102.247.229","cn":"zagreb404"}],"wg":[{"ip":"149.102.247.228","cn":"zagreb404"}]}},{"id":"us_montana-pf","name":"US Montana","country":"US","auto_region":true,"dns":"us-montana-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.91.23","cn":"montana401"}],"meta":[{"ip":"154.6.91.2","cn":"montana401"}],"ovpntcp":[{"ip":"154.6.91.24","cn":"montana401"}],"ovpnudp":[{"ip":"154.6.91.6","cn":"montana401"}],"wg":[{"ip":"154.6.91.27","cn":"montana401"}]}},{"id":"yerevan","name":"Armenia","country":"AM","auto_region":true,"dns":"yerevan.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"185.253.160.6","cn":"armenia403"}],"meta":[{"ip":"185.253.160.2","cn":"armenia403"}],"ovpntcp":[{"ip":"185.253.160.3","cn":"armenia403"}],"ovpnudp":[{"ip":"185.253.160.10","cn":"armenia403"}],"wg":[{"ip":"185.253.160.7","cn":"armenia403"}]}},{"id":"qatar","name":"Qatar","country":"QA","auto_region":true,"dns":"qatar.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"95.181.234.15","cn":"qatar404"}],"meta":[{"ip":"95.181.234.14","cn":"qatar404"}],"ovpntcp":[{"ip":"95.181.234.20","cn":"qatar404"}],"ovpnudp":[{"ip":"95.181.234.19","cn":"qatar404"}],"wg":[{"ip":"95.181.234.17","cn":"qatar404"}]}},{"id":"is","name":"Iceland","country":"IS","auto_region":true,"dns":"is.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"45.133.193.45","cn":"reykjavik401"}],"meta":[{"ip":"45.133.193.34","cn":"reykjavik401"}],"ovpntcp":[{"ip":"45.133.193.36","cn":"reykjavik401"}],"ovpnudp":[{"ip":"45.133.193.38","cn":"reykjavik401"}],"wg":[{"ip":"45.133.193.36","cn":"reykjavik401"}]}},{"id":"de_berlin","name":"DE Berlin","country":"DE","auto_region":true,"dns":"de-berlin.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"191.101.157.186","cn":"berlin422"}],"meta":[{"ip":"191.101.157.180","cn":"berlin422"}],"ovpntcp":[{"ip":"191.101.157.203","cn":"berlin422"}],"ovpnudp":[{"ip":"191.101.157.200","cn":"berlin422"}],"wg":[{"ip":"191.101.157.195","cn":"berlin422"}]}},{"id":"montenegro","name":"Montenegro","country":"ME","auto_region":true,"dns":"montenegro.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"176.125.229.3","cn":"montenegro403"}],"meta":[{"ip":"176.125.229.2","cn":"montenegro403"}],"ovpntcp":[{"ip":"176.125.229.5","cn":"montenegro403"}],"ovpnudp":[{"ip":"176.125.229.6","cn":"montenegro403"}],"wg":[{"ip":"176.125.229.3","cn":"montenegro403"}]}},{"id":"us3","name":"US West","country":"US","auto_region":true,"dns":"us3.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"184.170.252.211","cn":"phoenix411"}],"meta":[{"ip":"184.170.252.194","cn":"phoenix411"}],"ovpntcp":[{"ip":"184.170.252.211","cn":"phoenix411"}],"ovpnudp":[{"ip":"184.170.252.238","cn":"phoenix411"}],"wg":[{"ip":"184.170.252.225","cn":"phoenix411"}]}},{"id":"ca","name":"CA Montreal","country":"CA","auto_region":true,"dns":"ca-montreal.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"172.98.68.43","cn":"montreal409"}],"meta":[{"ip":"172.98.82.58","cn":"montreal409"}],"ovpntcp":[{"ip":"172.98.68.5","cn":"montreal409"}],"ovpnudp":[{"ip":"172.98.68.24","cn":"montreal409"}],"wg":[{"ip":"172.98.82.60","cn":"montreal409"}]}},{"id":"taiwan","name":"Taiwan","country":"TW","auto_region":true,"dns":"taiwan.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"173.244.49.86","cn":"taiwan406"}],"meta":[{"ip":"173.244.49.74","cn":"taiwan406"}],"ovpntcp":[{"ip":"173.244.49.77","cn":"taiwan406"}],"ovpnudp":[{"ip":"173.244.49.86","cn":"taiwan406"}],"wg":[{"ip":"173.244.49.97","cn":"taiwan406"}]}},{"id":"in","name":"India","country":"IN","auto_region":true,"dns":"in.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"166.0.218.202","cn":"mumbai414"}],"meta":[{"ip":"166.0.218.129","cn":"mumbai414"}],"ovpntcp":[{"ip":"166.0.218.193","cn":"mumbai414"}],"ovpnudp":[{"ip":"166.0.218.216","cn":"mumbai414"}],"wg":[{"ip":"166.0.218.208","cn":"mumbai414"}]}},{"id":"ro","name":"Romania","country":"RO","auto_region":true,"dns":"ro.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"143.244.54.128","cn":"romania407"}],"meta":[{"ip":"143.244.54.119","cn":"romania407"}],"ovpntcp":[{"ip":"143.244.54.134","cn":"romania407"}],"ovpnudp":[{"ip":"143.244.54.132","cn":"romania407"}],"wg":[{"ip":"143.244.54.140","cn":"romania407"}]}},{"id":"panama","name":"Panama","country":"PA","auto_region":true,"dns":"panama.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"91.90.126.78","cn":"panama407"}],"meta":[{"ip":"91.90.126.65","cn":"panama407"}],"ovpntcp":[{"ip":"91.90.126.67","cn":"panama407"}],"ovpnudp":[{"ip":"91.90.126.71","cn":"panama407"}],"wg":[{"ip":"91.90.126.75","cn":"panama407"}]}},{"id":"venezuela","name":"Venezuela","country":"VE","auto_region":true,"dns":"venezuela.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"95.181.237.31","cn":"venezuela405"}],"meta":[{"ip":"95.181.237.26","cn":"venezuela405"}],"ovpntcp":[{"ip":"95.181.237.27","cn":"venezuela405"}],"ovpnudp":[{"ip":"95.181.237.32","cn":"venezuela405"}],"wg":[{"ip":"95.181.237.36","cn":"venezuela405"}]}},{"id":"us_seattle","name":"US Seattle","country":"US","auto_region":true,"dns":"us-seattle.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"191.96.103.80","cn":"seattle406"}],"meta":[{"ip":"191.96.103.64","cn":"seattle406"}],"ovpntcp":[{"ip":"191.96.103.93","cn":"seattle406"}],"ovpnudp":[{"ip":"191.96.103.76","cn":"seattle406"}],"wg":[{"ip":"191.96.103.80","cn":"seattle406"}]}},{"id":"bogota","name":"Colombia","country":"CO","auto_region":true,"dns":"bogota.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"154.47.16.211","cn":"colombia404"}],"meta":[{"ip":"154.47.16.193","cn":"colombia404"}],"ovpntcp":[{"ip":"154.47.16.209","cn":"colombia404"}],"ovpnudp":[{"ip":"154.47.16.205","cn":"colombia404"}],"wg":[{"ip":"154.47.16.219","cn":"colombia404"}]}},{"id":"us_washington_dc","name":"US Washington DC","country":"US","auto_region":true,"dns":"us-washingtondc.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"102.129.235.215","cn":"washington446"}],"meta":[{"ip":"102.129.235.193","cn":"washington446"}],"ovpntcp":[{"ip":"102.129.235.195","cn":"washington446"}],"ovpnudp":[{"ip":"102.129.235.196","cn":"washington446"}],"wg":[{"ip":"102.129.235.194","cn":"washington446"}]}},{"id":"ad","name":"Andorra","country":"AD","auto_region":true,"dns":"ad.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"173.239.217.154","cn":"andorra407"}],"meta":[{"ip":"173.239.217.142","cn":"andorra407"}],"ovpntcp":[{"ip":"173.239.217.145","cn":"andorra407"}],"ovpnudp":[{"ip":"173.239.217.146","cn":"andorra407"}],"wg":[{"ip":"173.239.217.158","cn":"andorra407"}]}},{"id":"us_south_west","name":"US Texas","country":"US","auto_region":true,"dns":"us-texas.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"102.129.234.137","cn":"dallas412"}],"meta":[{"ip":"102.129.234.97","cn":"dallas412"}],"ovpntcp":[{"ip":"102.129.234.104","cn":"dallas412"}],"ovpnudp":[{"ip":"102.129.234.142","cn":"dallas412"}],"wg":[{"ip":"102.129.234.110","cn":"dallas412"}]}},{"id":"georgia","name":"Georgia","country":"GE","auto_region":true,"dns":"georgia.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"95.181.236.18","cn":"georgia404"}],"meta":[{"ip":"95.181.236.14","cn":"georgia404"}],"ovpntcp":[{"ip":"95.181.236.16","cn":"georgia404"}],"ovpnudp":[{"ip":"95.181.236.21","cn":"georgia404"}],"wg":[{"ip":"95.181.236.24","cn":"georgia404"}]}},{"id":"us_houston","name":"US Houston","country":"US","auto_region":true,"dns":"us-houston.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"37.19.221.48","cn":"houston433"}],"meta":[{"ip":"37.19.221.28","cn":"houston433"}],"ovpntcp":[{"ip":"37.19.221.31","cn":"houston433"}],"ovpnudp":[{"ip":"37.19.221.36","cn":"houston433"}],"wg":[{"ip":"37.19.221.31","cn":"houston433"}]}},{"id":"lu","name":"Luxembourg","country":"LU","auto_region":true,"dns":"lu.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"37.46.113.172","cn":"luxembourg412"}],"meta":[{"ip":"37.46.113.153","cn":"luxembourg412"}],"ovpntcp":[{"ip":"37.46.113.171","cn":"luxembourg412"}],"ovpnudp":[{"ip":"37.46.113.181","cn":"luxembourg412"}],"wg":[{"ip":"37.46.113.158","cn":"luxembourg412"}]}},{"id":"lt","name":"Lithuania","country":"LT","auto_region":true,"dns":"lt.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"194.32.122.73","cn":"vilnius403"}],"meta":[{"ip":"194.32.122.60","cn":"vilnius403"}],"ovpntcp":[{"ip":"194.32.122.71","cn":"vilnius403"}],"ovpnudp":[{"ip":"194.32.122.71","cn":"vilnius403"}],"wg":[{"ip":"194.32.122.72","cn":"vilnius403"}]}},{"id":"aus_perth","name":"AU Perth","country":"AU","auto_region":true,"dns":"aus-perth.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"179.61.228.40","cn":"perth403"}],"meta":[{"ip":"43.250.205.57","cn":"perth403"}],"ovpntcp":[{"ip":"179.61.228.17","cn":"perth403"}],"ovpnudp":[{"ip":"179.61.228.17","cn":"perth403"}],"wg":[{"ip":"179.61.228.50","cn":"perth403"}]}},{"id":"malta","name":"Malta","country":"MT","auto_region":true,"dns":"malta.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"176.125.230.35","cn":"malta405"}],"meta":[{"ip":"176.125.230.29","cn":"malta405"}],"ovpntcp":[{"ip":"176.125.230.35","cn":"malta405"}],"ovpnudp":[{"ip":"176.125.230.31","cn":"malta405"}],"wg":[{"ip":"176.125.230.31","cn":"malta405"}]}},{"id":"us_florida","name":"US Florida","country":"US","auto_region":true,"dns":"us-florida.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"102.129.153.109","cn":"miami426"}],"meta":[{"ip":"102.129.153.5","cn":"miami426"}],"ovpntcp":[{"ip":"102.129.153.114","cn":"miami426"}],"ovpnudp":[{"ip":"102.129.153.128","cn":"miami426"}],"wg":[{"ip":"102.129.153.108","cn":"miami426"}]}},{"id":"au_australia-so","name":"Australia Streaming Optimized","country":"AU","auto_region":false,"dns":"au-australia-so.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"154.6.151.202","cn":"melbourne434"}],"meta":[{"ip":"154.6.151.8","cn":"melbourne434"}],"ovpntcp":[{"ip":"154.6.151.210","cn":"melbourne434"}],"ovpnudp":[{"ip":"154.6.151.196","cn":"melbourne434"}],"wg":[{"ip":"154.6.151.191","cn":"melbourne434"}]}},{"id":"pe_peru-pf","name":"Peru","country":"PE","auto_region":true,"dns":"pe-peru-pf.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"84.247.99.15","cn":"peru401"}],"meta":[{"ip":"84.247.99.2","cn":"peru401"}],"ovpntcp":[{"ip":"84.247.99.6","cn":"peru401"}],"ovpnudp":[{"ip":"84.247.99.11","cn":"peru401"}],"wg":[{"ip":"84.247.99.27","cn":"peru401"}]}},{"id":"ca_vancouver","name":"CA Vancouver","country":"CA","auto_region":true,"dns":"ca-vancouver.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"181.41.202.126","cn":"vancouver431"}],"meta":[{"ip":"181.41.202.5","cn":"vancouver431"}],"ovpntcp":[{"ip":"181.41.202.106","cn":"vancouver431"}],"ovpnudp":[{"ip":"181.41.202.107","cn":"vancouver431"}],"wg":[{"ip":"181.41.202.120","cn":"vancouver431"}]}},{"id":"us_new_hampshire-pf","name":"US New Hampshire","country":"US","auto_region":true,"dns":"us-new-hampshire-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.13.154","cn":"newhampshire401"}],"meta":[{"ip":"154.6.13.130","cn":"newhampshire401"}],"ovpntcp":[{"ip":"154.6.13.133","cn":"newhampshire401"}],"ovpnudp":[{"ip":"154.6.13.141","cn":"newhampshire401"}],"wg":[{"ip":"154.6.13.148","cn":"newhampshire401"}]}},{"id":"nigeria","name":"Nigeria","country":"NG","auto_region":true,"dns":"nigeria.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"146.70.65.141","cn":"nigeria405"}],"meta":[{"ip":"146.70.65.130","cn":"nigeria405"}],"ovpntcp":[{"ip":"146.70.65.134","cn":"nigeria405"}],"ovpnudp":[{"ip":"146.70.65.137","cn":"nigeria405"}],"wg":[{"ip":"146.70.65.135","cn":"nigeria405"}]}},{"id":"uk_southampton","name":"UK Southampton","country":"GB","auto_region":true,"dns":"uk-southampton.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"98.159.234.105","cn":"southampton403"}],"meta":[{"ip":"98.159.234.83","cn":"southampton403"}],"ovpntcp":[{"ip":"98.159.234.104","cn":"southampton403"}],"ovpnudp":[{"ip":"98.159.234.120","cn":"southampton403"}],"wg":[{"ip":"98.159.234.117","cn":"southampton403"}]}},{"id":"us_alaska-pf","name":"US Alaska","country":"US","auto_region":true,"dns":"us-alaska-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.93.155","cn":"alaska401"}],"meta":[{"ip":"154.6.93.130","cn":"alaska401"}],"ovpntcp":[{"ip":"154.6.93.141","cn":"alaska401"}],"ovpnudp":[{"ip":"154.6.93.145","cn":"alaska401"}],"wg":[{"ip":"154.6.93.151","cn":"alaska401"}]}},{"id":"uk_manchester","name":"UK Manchester","country":"GB","auto_region":true,"dns":"uk-manchester.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"45.133.172.77","cn":"manchester421"}],"meta":[{"ip":"45.133.172.66","cn":"manchester421"}],"ovpntcp":[{"ip":"45.133.172.90","cn":"manchester421"}],"ovpnudp":[{"ip":"45.133.172.79","cn":"manchester421"}],"wg":[{"ip":"45.133.172.70","cn":"manchester421"}]}},{"id":"us_denver","name":"US Denver","country":"US","auto_region":true,"dns":"us-denver.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"181.41.206.22","cn":"denver406"}],"meta":[{"ip":"181.41.206.2","cn":"denver406"}],"ovpntcp":[{"ip":"181.41.206.27","cn":"denver406"}],"ovpnudp":[{"ip":"181.41.206.20","cn":"denver406"}],"wg":[{"ip":"181.41.206.18","cn":"denver406"}]}},{"id":"us_michigan-pf","name":"US Michigan","country":"US","auto_region":true,"dns":"us-michigan-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.86.46","cn":"michigan402"}],"meta":[{"ip":"154.6.86.29","cn":"michigan402"}],"ovpntcp":[{"ip":"154.6.86.33","cn":"michigan402"}],"ovpnudp":[{"ip":"154.6.86.34","cn":"michigan402"}],"wg":[{"ip":"154.6.86.37","cn":"michigan402"}]}},{"id":"al","name":"Albania","country":"AL","auto_region":true,"dns":"al.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"31.171.154.134","cn":"tirana401"}],"meta":[{"ip":"31.171.154.130","cn":"tirana401"}],"ovpntcp":[{"ip":"31.171.154.139","cn":"tirana401"}],"ovpnudp":[{"ip":"31.171.154.131","cn":"tirana401"}],"wg":[{"ip":"31.171.154.131","cn":"tirana401"}]}},{"id":"ae","name":"United Arab Emirates","country":"AE","auto_region":true,"dns":"ae.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"217.138.193.166","cn":"dubai404"}],"meta":[{"ip":"45.9.250.62","cn":"dubai404"}],"ovpntcp":[{"ip":"217.138.193.172","cn":"dubai404"}],"ovpnudp":[{"ip":"217.138.193.174","cn":"dubai404"}],"wg":[{"ip":"217.138.193.170","cn":"dubai404"}]}},{"id":"ca_toronto","name":"CA Toronto","country":"CA","auto_region":true,"dns":"ca-toronto.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"191.96.36.15","cn":"toronto414"}],"meta":[{"ip":"191.96.36.3","cn":"toronto414"}],"ovpntcp":[{"ip":"191.96.36.23","cn":"toronto414"}],"ovpnudp":[{"ip":"191.96.36.23","cn":"toronto414"}],"wg":[{"ip":"191.96.36.8","cn":"toronto414"}]}},{"id":"dz","name":"Algeria","country":"DZ","auto_region":true,"dns":"dz.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"176.125.228.18","cn":"algiers404"}],"meta":[{"ip":"176.125.228.14","cn":"algiers404"}],"ovpntcp":[{"ip":"176.125.228.24","cn":"algiers404"}],"ovpnudp":[{"ip":"176.125.228.17","cn":"algiers404"}],"wg":[{"ip":"176.125.228.22","cn":"algiers404"}]}},{"id":"ua","name":"Ukraine","country":"UA","auto_region":true,"dns":"ua.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"84.239.42.21","cn":"kiev408"}],"meta":[{"ip":"84.239.42.1","cn":"kiev408"}],"ovpntcp":[{"ip":"84.239.42.14","cn":"kiev408"}],"ovpnudp":[{"ip":"84.239.42.15","cn":"kiev408"}],"wg":[{"ip":"84.239.42.25","cn":"kiev408"}]}},{"id":"us_tennessee-pf","name":"US Tennessee","country":"US","auto_region":true,"dns":"us-tennessee-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.83.3","cn":"tennessee401"}],"meta":[{"ip":"154.6.83.2","cn":"tennessee401"}],"ovpntcp":[{"ip":"154.6.83.16","cn":"tennessee401"}],"ovpnudp":[{"ip":"154.6.83.19","cn":"tennessee401"}],"wg":[{"ip":"154.6.83.15","cn":"tennessee401"}]}},{"id":"vietnam","name":"Vietnam","country":"VN","auto_region":true,"dns":"vietnam.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"149.18.84.59","cn":"vietnam403"}],"meta":[{"ip":"149.18.84.50","cn":"vietnam403"}],"ovpntcp":[{"ip":"149.18.84.62","cn":"vietnam403"}],"ovpnudp":[{"ip":"149.18.84.56","cn":"vietnam403"}],"wg":[{"ip":"149.18.84.57","cn":"vietnam403"}]}},{"id":"mongolia","name":"Mongolia","country":"MN","auto_region":true,"dns":"mongolia.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"192.142.227.20","cn":"mongolia405"}],"meta":[{"ip":"192.142.227.13","cn":"mongolia405"}],"ovpntcp":[{"ip":"192.142.227.19","cn":"mongolia405"}],"ovpnudp":[{"ip":"192.142.227.24","cn":"mongolia405"}],"wg":[{"ip":"192.142.227.23","cn":"mongolia405"}]}},{"id":"ee","name":"Estonia","country":"EE","auto_region":true,"dns":"ee.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"165.231.182.118","cn":"talinn409"}],"meta":[{"ip":"165.231.182.109","cn":"talinn409"}],"ovpntcp":[{"ip":"165.231.182.117","cn":"talinn409"}],"ovpnudp":[{"ip":"165.231.182.120","cn":"talinn409"}],"wg":[{"ip":"165.231.182.111","cn":"talinn409"}]}},{"id":"bo_bolivia-pf","name":"Bolivia","country":"BO","auto_region":true,"dns":"bo-bolivia-pf.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"84.247.91.25","cn":"bolivia401"}],"meta":[{"ip":"84.247.91.2","cn":"bolivia401"}],"ovpntcp":[{"ip":"84.247.91.22","cn":"bolivia401"}],"ovpnudp":[{"ip":"84.247.91.6","cn":"bolivia401"}],"wg":[{"ip":"84.247.91.7","cn":"bolivia401"}]}},{"id":"us_wisconsin-pf","name":"US Wisconsin","country":"US","auto_region":true,"dns":"us-wisconsin-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.88.4","cn":"wisconsin401"}],"meta":[{"ip":"154.6.88.2","cn":"wisconsin401"}],"ovpntcp":[{"ip":"154.6.88.19","cn":"wisconsin401"}],"ovpnudp":[{"ip":"154.6.88.22","cn":"wisconsin401"}],"wg":[{"ip":"154.6.88.8","cn":"wisconsin401"}]}},{"id":"us_maine-pf","name":"US Maine","country":"US","auto_region":true,"dns":"us-maine-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.12.153","cn":"maine401"}],"meta":[{"ip":"154.6.12.130","cn":"maine401"}],"ovpntcp":[{"ip":"154.6.12.150","cn":"maine401"}],"ovpnudp":[{"ip":"154.6.12.140","cn":"maine401"}],"wg":[{"ip":"154.6.12.141","cn":"maine401"}]}},{"id":"greenland","name":"Greenland","country":"GL","auto_region":true,"dns":"greenland.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"91.90.120.148","cn":"greenland404"}],"meta":[{"ip":"91.90.120.145","cn":"greenland404"}],"ovpntcp":[{"ip":"91.90.120.152","cn":"greenland404"}],"ovpnudp":[{"ip":"91.90.120.159","cn":"greenland404"}],"wg":[{"ip":"91.90.120.148","cn":"greenland404"}]}},{"id":"br","name":"Brazil","country":"BR","auto_region":true,"dns":"br.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"146.70.98.39","cn":"saopaolo407"}],"meta":[{"ip":"146.70.98.34","cn":"saopaolo407"}],"ovpntcp":[{"ip":"146.70.98.41","cn":"saopaolo407"}],"ovpnudp":[{"ip":"146.70.98.39","cn":"saopaolo407"}],"wg":[{"ip":"146.70.98.39","cn":"saopaolo407"}]}},{"id":"gt_guatemala-pf","name":"Guatemala","country":"GT","auto_region":true,"dns":"gt-guatemala-pf.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"84.247.95.23","cn":"guatemala401"}],"meta":[{"ip":"84.247.95.2","cn":"guatemala401"}],"ovpntcp":[{"ip":"84.247.95.21","cn":"guatemala401"}],"ovpnudp":[{"ip":"84.247.95.14","cn":"guatemala401"}],"wg":[{"ip":"84.247.95.18","cn":"guatemala401"}]}},{"id":"us_arkansas-pf","name":"US Arkansas","country":"US","auto_region":true,"dns":"us-arkansas-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.81.5","cn":"littlerock401"}],"meta":[{"ip":"154.6.81.2","cn":"littlerock401"}],"ovpntcp":[{"ip":"154.6.81.6","cn":"littlerock401"}],"ovpnudp":[{"ip":"154.6.81.20","cn":"littlerock401"}],"wg":[{"ip":"154.6.81.27","cn":"littlerock401"}]}},{"id":"us_kansas-pf","name":"US Kansas","country":"US","auto_region":true,"dns":"us-kansas-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"84.239.31.8","cn":"kansas402"}],"meta":[{"ip":"84.239.31.2","cn":"kansas402"}],"ovpntcp":[{"ip":"84.239.31.20","cn":"kansas402"}],"ovpnudp":[{"ip":"84.239.31.17","cn":"kansas402"}],"wg":[{"ip":"84.239.31.10","cn":"kansas402"}]}},{"id":"us_north_dakota-pf","name":"US North Dakota","country":"US","auto_region":true,"dns":"us-north-dakota-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"84.239.48.6","cn":"northdakota402"}],"meta":[{"ip":"84.239.48.2","cn":"northdakota402"}],"ovpntcp":[{"ip":"84.239.48.12","cn":"northdakota402"}],"ovpnudp":[{"ip":"84.239.48.11","cn":"northdakota402"}],"wg":[{"ip":"84.239.48.7","cn":"northdakota402"}]}},{"id":"us_atlanta","name":"US Atlanta","country":"US","auto_region":true,"dns":"us-atlanta.privacy.network","port_forward":false,"geo":false,"servers":{"ikev2":[{"ip":"5.182.110.252","cn":"atlanta436"}],"meta":[{"ip":"5.182.110.225","cn":"atlanta436"}],"ovpntcp":[{"ip":"5.182.110.238","cn":"atlanta436"}],"ovpnudp":[{"ip":"5.182.110.240","cn":"atlanta436"}],"wg":[{"ip":"5.182.110.228","cn":"atlanta436"}]}},{"id":"za","name":"South Africa","country":"ZA","auto_region":true,"dns":"za.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"154.47.30.51","cn":"johannesburg411"}],"meta":[{"ip":"154.47.30.31","cn":"johannesburg411"}],"ovpntcp":[{"ip":"154.47.30.50","cn":"johannesburg411"}],"ovpnudp":[{"ip":"154.47.30.44","cn":"johannesburg411"}],"wg":[{"ip":"154.47.30.50","cn":"johannesburg411"}]}},{"id":"denmark_2","name":"DK Streaming Optimized","country":"DK","auto_region":false,"dns":"denmark-2.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"188.126.94.58","cn":"copenhagen405"}],"meta":[{"ip":"188.126.94.34","cn":"copenhagen405"}],"ovpntcp":[{"ip":"188.126.94.42","cn":"copenhagen405"}],"ovpnudp":[{"ip":"188.126.94.50","cn":"copenhagen405"}],"wg":[{"ip":"188.126.94.53","cn":"copenhagen405"}]}},{"id":"ba","name":"Bosnia and Herzegovina","country":"BA","auto_region":true,"dns":"ba.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"98.159.36.138","cn":"sarajevo403"}],"meta":[{"ip":"98.159.36.128","cn":"sarajevo403"}],"ovpntcp":[{"ip":"98.159.36.130","cn":"sarajevo403"}],"ovpnudp":[{"ip":"98.159.36.139","cn":"sarajevo403"}],"wg":[{"ip":"98.159.36.134","cn":"sarajevo403"}]}},{"id":"au_adelaide-pf","name":"AU Adelaide","country":"AU","auto_region":true,"dns":"au-adelaide-pf.privacy.network","port_forward":true,"geo":false,"servers":{"ikev2":[{"ip":"173.244.62.23","cn":"adelaide401"}],"meta":[{"ip":"173.244.62.2","cn":"adelaide401"}],"ovpntcp":[{"ip":"173.244.62.11","cn":"adelaide401"}],"ovpnudp":[{"ip":"173.244.62.29","cn":"adelaide401"}],"wg":[{"ip":"173.244.62.22","cn":"adelaide401"}]}},{"id":"cambodia","name":"Cambodia","country":"KH","auto_region":true,"dns":"cambodia.privacy.network","port_forward":true,"geo":true,"servers":{"ikev2":[{"ip":"188.215.235.99","cn":"cambodia401"}],"meta":[{"ip":"188.215.235.98","cn":"cambodia401"}],"ovpntcp":[{"ip":"188.215.235.109","cn":"cambodia401"}],"ovpnudp":[{"ip":"188.215.235.106","cn":"cambodia401"}],"wg":[{"ip":"188.215.235.108","cn":"cambodia401"}]}},{"id":"us_vermont-pf","name":"US Vermont","country":"US","auto_region":true,"dns":"us-vermont-pf.privacy.network","port_forward":false,"geo":true,"servers":{"ikev2":[{"ip":"154.6.94.147","cn":"vermont401"}],"meta":[{"ip":"154.6.94.130","cn":"vermont401"}],"ovpntcp":[{"ip":"154.6.94.148","cn":"vermont401"}],"ovpnudp":[{"ip":"154.6.94.139","cn":"vermont401"}],"wg":[{"ip":"154.6.94.136","cn":"vermont401"}]}}]} diff --git a/PIA VPN dev.app/Roboto-Light.ttf b/PIA VPN dev.app/Roboto-Light.ttf new file mode 100755 index 000000000..219063a57 Binary files /dev/null and b/PIA VPN dev.app/Roboto-Light.ttf differ diff --git a/PIA VPN dev.app/Roboto-Medium.ttf b/PIA VPN dev.app/Roboto-Medium.ttf new file mode 100755 index 000000000..1a7f3b0bb Binary files /dev/null and b/PIA VPN dev.app/Roboto-Medium.ttf differ diff --git a/PIA VPN dev.app/Roboto-Regular.ttf b/PIA VPN dev.app/Roboto-Regular.ttf new file mode 100755 index 000000000..2c97eeadf Binary files /dev/null and b/PIA VPN dev.app/Roboto-Regular.ttf differ diff --git a/PIA VPN dev.app/Roboto-Thin.ttf b/PIA VPN dev.app/Roboto-Thin.ttf new file mode 100755 index 000000000..b74a4fd1a Binary files /dev/null and b/PIA VPN dev.app/Roboto-Thin.ttf differ diff --git a/PIA VPN dev.app/SubscriptionTile.nib b/PIA VPN dev.app/SubscriptionTile.nib new file mode 100644 index 000000000..b004f750b Binary files /dev/null and b/PIA VPN dev.app/SubscriptionTile.nib differ diff --git a/PIA VPN dev.app/SubscriptionTileCollectionViewCell.nib/objects-12.3+.nib b/PIA VPN dev.app/SubscriptionTileCollectionViewCell.nib/objects-12.3+.nib new file mode 100644 index 000000000..59cb3bb1e Binary files /dev/null and b/PIA VPN dev.app/SubscriptionTileCollectionViewCell.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/SubscriptionTileCollectionViewCell.nib/runtime.nib b/PIA VPN dev.app/SubscriptionTileCollectionViewCell.nib/runtime.nib new file mode 100644 index 000000000..df2524aaa Binary files /dev/null and b/PIA VPN dev.app/SubscriptionTileCollectionViewCell.nib/runtime.nib differ diff --git a/PIA VPN dev.app/UsageTile.nib b/PIA VPN dev.app/UsageTile.nib new file mode 100644 index 000000000..201f0d506 Binary files /dev/null and b/PIA VPN dev.app/UsageTile.nib differ diff --git a/PIA VPN dev.app/UsageTileCollectionViewCell.nib/objects-12.3+.nib b/PIA VPN dev.app/UsageTileCollectionViewCell.nib/objects-12.3+.nib new file mode 100644 index 000000000..bcd26e6ba Binary files /dev/null and b/PIA VPN dev.app/UsageTileCollectionViewCell.nib/objects-12.3+.nib differ diff --git a/PIA VPN dev.app/UsageTileCollectionViewCell.nib/runtime.nib b/PIA VPN dev.app/UsageTileCollectionViewCell.nib/runtime.nib new file mode 100644 index 000000000..5ef67ccce Binary files /dev/null and b/PIA VPN dev.app/UsageTileCollectionViewCell.nib/runtime.nib differ diff --git a/PIA VPN dev.app/_CodeSignature/CodeResources b/PIA VPN dev.app/_CodeSignature/CodeResources new file mode 100644 index 000000000..bc782dfc1 --- /dev/null +++ b/PIA VPN dev.app/_CodeSignature/CodeResources @@ -0,0 +1,7864 @@ + + + + + files + + ActiveDedicatedIpHeaderViewCell.nib + + xLIw4AVqXbrEYPIxEfr0R5gZoB4= + + AppIcon60x60@2x.png + + SbM4HE3STUpxUh2DLwzScNmKdic= + + AppIcon76x76@2x~ipad.png + + oiwz3hYM41Ih3JBNsIQJP1840EA= + + Assets.car + + o793WERSHSl/Ar5FjU09gVH7zmM= + + Components.plist + + pisJjiG9CodMn+P++UcjphlT2CQ= + + ConnectionTile.nib + + 8emE7NAvqHIVhhqV+1z+D8sTRBo= + + ConnectionTileCollectionViewCell.nib/objects-12.3+.nib + + Agg4gbliWcGisvHN4CIiUZjLtpA= + + ConnectionTileCollectionViewCell.nib/runtime.nib + + c3/jYsMi9VDQSTV6BfUh4J9rgiw= + + CustomNetworkCollectionViewCell.nib/objects-12.3+.nib + + 20jgN+1MuYlIMjOgNkzuNdzLbP4= + + CustomNetworkCollectionViewCell.nib/runtime.nib + + WlcX/pxfWjRLufVjBe9LyjdHN0s= + + DNS.plist + + HnAp5uzjOiXgNiwv6FvCNyFYm98= + + DedicatedIPTitleHeaderViewCell.nib + + X6f4vsfmnQy8CR8q1/l2p46Ncqk= + + DedicatedIpEmptyHeaderViewCell.nib + + M6x14F/gJBpaXXD17U6fFBAd884= + + DedicatedIpRowViewCell.nib + + SsezXzcRUjOqkykKGq7R5f5wiec= + + FavoriteServersTile.nib + + D/HsAzzHKSzOPiHui2PoRwLuvp0= + + FavoriteServersTileCollectionViewCell.nib/objects-12.3+.nib + + nQZzixkJXzyjsamzvdaeaCQVMig= + + FavoriteServersTileCollectionViewCell.nib/runtime.nib + + 8EsrmOrSpEMsKzSwHa9/1ljg+Js= + + Flags-dev.plist + + nAdI9qCmWGhJTNk5p4ZrS7t7F9Y= + + Frameworks/PIACSI.framework/Info.plist + + pAgmhvOx+ttiJrsquW85U6Mc5aM= + + Frameworks/PIACSI.framework/PIACSI + + UfucBRsJcI1QrCHd3tKz1OKynV4= + + Frameworks/PIACSI.framework/_CodeSignature/CodeResources + + 83h8E6S6NvyRArgTd6fm+CL4BZA= + + Frameworks/PIAKPI.framework/Info.plist + + nvMD58Pn9TT2kC7Ifc0XZdJ1IQ0= + + Frameworks/PIAKPI.framework/PIAKPI + + AeXyOcKqYD4PWvfmAmpk1MMxo9s= + + Frameworks/PIAKPI.framework/_CodeSignature/CodeResources + + f8Ja752NwiEfa13YgTXfM9aziI0= + + Frameworks/PIARegions.framework/Info.plist + + 1tJ+m8+dw/cFodi2bzU5k7uPTJ4= + + Frameworks/PIARegions.framework/PIARegions + + uiUS0nfdErtP/mbdRKkGixk9lm0= + + Frameworks/PIARegions.framework/_CodeSignature/CodeResources + + t88j+zx9ANp5BmLD90jqelohcl8= + + Frameworks/account.framework/Info.plist + + z+drOuEngEvNK0w6F0e1xAUTBU0= + + Frameworks/account.framework/_CodeSignature/CodeResources + + OnDLVa2tMG/+4k1O5ovJCWmGuJk= + + Frameworks/account.framework/account + + ffGPbwL++Iay4dMwqYc2MjqbDIo= + + Frameworks/openssl.framework/Info.plist + + 5z4kgULU81dtbcBAWWUGf1TqMKs= + + Frameworks/openssl.framework/_CodeSignature/CodeResources + + NYXwDZRvKdyvvrANlBpZvwtaVhc= + + Frameworks/openssl.framework/openssl + + GewdvpXZN3yQBfuRF/h2i81UV9Q= + + IPTile.nib + + DTCWGPYZxE/0tQ5bDmgbfeDU7Xs= + + IPTileCollectionViewCell.nib/objects-12.3+.nib + + lV9pvylDOz+RAgnD8Dfvj6E42x8= + + IPTileCollectionViewCell.nib/runtime.nib + + Bo6ONxZDJ7KfyUHeyCXiuZazE1E= + + Info.plist + + h0oGrUeu7VQii7K06DIDSXgHLVo= + + Launch Screen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib + + /UfV8qZ4BvowKxr6amOAQxy42CM= + + Launch Screen.storyboardc/Info.plist + + n2t8gsDpfE6XkhG31p7IQJRxTxU= + + Launch Screen.storyboardc/UIViewController-01J-lp-oVM.nib + + ZVgM1+KwZcZnwhgaI0F7Bt1ba2c= + + MessagesTile.nib + + xGvCrSp7694nwWVNnIdjk6sn114= + + MessagesTileCollectionViewCell.nib/objects-12.3+.nib + + Imgs/vQwzP/odpCS5+LjhMjIcJc= + + MessagesTileCollectionViewCell.nib/runtime.nib + + Qjxbpk6LxQYB6iET6iPzxsoxRmw= + + NetworkCollectionViewCell.nib/objects-12.3+.nib + + T8SCVyzixaJ2pJWVOlv2bxHU7E4= + + NetworkCollectionViewCell.nib/runtime.nib + + oAe3SsyxWcygVRHjnovbf0VDM5s= + + NetworkFooterCollectionViewCell.nib/objects-12.3+.nib + + v1JyIX2Ru88tYDuI4bqYgCxrKZs= + + NetworkFooterCollectionViewCell.nib/runtime.nib + + wrca/u23jk5yZfSED6ldmiQe0ZU= + + PIA-RSA-4096.pem + + 3qHvNikZqOiKtbZEW5+oygpFyfw= + + PIACard.nib + + xpCifyBNpFezBnvbEolGd+sSxyY= + + PIAHeaderCollectionViewCell.nib/objects-12.3+.nib + + 1+Jd6KsDp2+ejUPGvhW4xXnfzwQ= + + PIAHeaderCollectionViewCell.nib/runtime.nib + + sO6PZzv1U6ueINwQJ3kp8b6rU2E= + + PIALibrary_PIALibrary.bundle/Assets.car + + 8h6Hyf4U9/+JlpRmAN3vBaPEjrw= + + PIALibrary_PIALibrary.bundle/Info.plist + + U4V2uvQAAIulAUfBSoJQTzWiVN4= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + dytHgVNc10hWhKQW+WIDasbWdTU= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib + + OVb1ASokoqm9FsqgYqS4ykOLvTk= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + qEnPzvZ7YJ2malb9v8b6uU1qRtI= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib + + BnH89TJFPy09hwlepgmy1qX8w5I= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist + + tvSnglTgEmfEVDs4Pqzq89zCWdk= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + htQTSxHbapTjr/KU4MZ+BReh+fg= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + CJa19sBIiRCsSpkmvlAK9WVgIUc= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib + + DClrKMNBhP7R57XPbVZNLZEkhHY= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib + + RII82MT1u8xiVhoF6z8GAPWRauw= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + YpRMevT/Hk92B7qxIoBZNubmhVo= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + bJ8pWQoqUwPJh2R449Z5iB80fgw= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + XIT4vTE0sbcaxPw4Ukcc10AudMU= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + 8QYAr5CSJVq9J2M/WNeKrHxyH4k= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + /KugdZ7rq/us89d7xS8Y4W80uoE= + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + lAQN56rjGXobwkMhOfbs34FT+S8= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist + + /pYtZWavELI0+6nEkTUa0WNFSew= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + QLgeyu0ZVc/lDmyITQfrBSRT2Hk= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + gA8eOIpUQd1BEBgO/w9hDFS+JxU= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + GzhYGB3AyZ0wytBn61POuwdsJ7E= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + sQtUseVfpjT4CFtCBgvBwDjWfQA= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory + + gjf0PUSrcJskfjBJ7fSOp0hPRqU= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements + + OnX22wWFKRSOFN1+obRynMCeyXM= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 + + Xek7S2WT/EJTVDHjzmsxCQMBPMg= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources + + ypAPfIR7Xyk9v8RohL9v2uz3dB4= + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature + + 2jmj7l5rSw0yVb/vlWAYkK/YBwk= + + PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings + + hash + + KDACaW+muq3Q7S2KFi/tSoBrOA0= + + optional + + + PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings + + hash + + q69blyRGQI14B9CBKT9Rsw4dq0k= + + optional + + + PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings + + hash + + BkACZwewt5pWHuYeiW8u/ttymCg= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings + + hash + + ImqHeuQyhd4vbb7tX6gDpc0Uws4= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/UI.strings + + hash + + JEB6TYMiWHIJ3Fwzv9hwS3X5B9c= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings + + hash + + 0U+OaxIpF3m54GcZw6Rj0FT9IQU= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings + + hash + + ULQLCKJ1Tkx5LYNqw+wZAPpz+fc= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/UI.strings + + hash + + 1964G9tW/vLUljfWDybLqmj8ovo= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings + + hash + + j/jLkt7lT5WaqzpSmS2HeZ2YT7g= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings + + hash + + EZ9QZ7PSibfcWSeEETK4rR/PkKE= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/UI.strings + + hash + + 8v4J37YS+jZq3LBvpRfFdfrmOjo= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings + + hash + + BwdYyKtC03avQBNFX31HfqSElzI= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings + + hash + + /cuvVUGtYOlubi9pgRpN8GF6eaQ= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings + + hash + + iiP5bcCQB5ClycQCkVGeHIMUAks= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings + + hash + + lx4/QzIqPJcVTvU4PUA9DuA+iR0= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings + + hash + + vRPh7xNvA8CBlDbvqId98Ppaol4= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings + + hash + + IbgvE2UN4PxyRd+exu9NKENUaI0= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings + + hash + + KoygslQ7+C06O61A0YHLMJPIhd8= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings + + hash + + Ed4oYGhilkGVvO6AshjBjzdE+7w= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/UI.strings + + hash + + Y50/iDsqGezjtBuqSlPo8jymMAc= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings + + hash + + 8OHVfUCzQp3y5Avt0qvL0KEijp8= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings + + hash + + nNEDjklKvB3EYDy3z/dKvk0Y3Sc= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings + + hash + + +2YIistydmlPjDts2u1ROqKtWqI= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings + + hash + + RbM1jidNxxT0GrCW5Bp4AJ2C10U= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings + + hash + + v+qEVshU1lPCEIX6p/5VNVvHCsE= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings + + hash + + XSewfIvou+2vfPzfd4L1JobLejU= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings + + hash + + j/ZhhE8EhAk/Lumf0d8hAl0mnM0= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings + + hash + + KhJ/QqRfNp4OZfzpif4GtcBF8bI= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings + + hash + + xDMWYimFFDfSHhe2YZpdtrl2g8k= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings + + hash + + uwWBmqf4ftnCEhc6CREp8ByROW4= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings + + hash + + NyXHmGW4hA/Eauh4ij9O5S5WhTA= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings + + hash + + YZpZdbu3r3xtH/jvKMalDSa3lOc= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings + + hash + + yqehLrthKrrux3wlT4BXD2o86VM= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings + + hash + + 6OMfwEOtzCuZV03uZytGep2fVcM= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings + + hash + + K6FfGb4sRyZ+8fUCnq80qKRGipc= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings + + hash + + jdPps229/rIXz+/ddHNG9FuKBhQ= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings + + hash + + fbM6TjAWhkqwQRqlFgXqxwrx+8k= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings + + hash + + 5JKfMEQAm3AUcBKlsob0yfJRkQk= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings + + hash + + 01ji1w1oANjR7h5TRr6cBlyaRGo= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings + + hash + + ZPLrICgFyE180EQFQQsAPW2T0LY= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings + + hash + + Ke55XO9cpqEQhKUHTr3HEvi0aUM= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings + + hash + + rfmjmvw733cPOhxZ0RizNQfXkSE= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings + + hash + + awJpWTrrqH31sd1t1ndiEy4cN/A= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/UI.strings + + hash + + QMaBIt1A8kjNOstov8L0lchT5Ec= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings + + hash + + 5J5E4i04UUqsWy3SQZN1zcKIZaQ= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings + + hash + + 55QLf0o5XG8IWfXbQ6KvFWToA+4= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings + + hash + + hfdFuAQLTfdHleeMkh4YCtlcNBY= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings + + hash + + R49azaTbZXexzZ4fO2KAO8IQIW4= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings + + hash + + B3OiNtJOoqFlNs77EeQh3/YlwiU= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings + + hash + + athEoNydnFVAkLxqKvlUTv5EfZg= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings + + hash + + 6aHDe64C6X+IcTDg3C39b+SM9Ls= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings + + hash + + InQh2yXFC6brp+xf2gtnVDZtsuY= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings + + hash + + 7NuRLJG/PUbRlsl/6dZTfboVNfQ= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings + + hash + + hBHKqa7nicnE6j15W8iBNQQdsws= + + optional + + + PIAWireguard_PIAWireguard.bundle/Info.plist + + /Sr7lQ3v9dlVi0s0lsUfQz9dK84= + + PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem + + 3qHvNikZqOiKtbZEW5+oygpFyfw= + + PIAWireguard_PIAWireguard.bundle/PIA.der + + HjU73bSJKXFVdCTqzHVin0iWAak= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory + + 1goWa+U5od4AnpP1zIi6N43ps+k= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements + + OnX22wWFKRSOFN1+obRynMCeyXM= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 + + ae4UnuV7lDFjF1toM8Tj2NbLvS4= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources + + G9y6xZfvG8s3gN1rZw4IpRPNIIc= + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature + + 2jmj7l5rSw0yVb/vlWAYkK/YBwk= + + PkgInfo + + n57qDP4tZfLD1rCS43W0B4LQjzE= + + PlugIns/PIA VPN AdBlocker.appex/Info.plist + + /cOwrPQkWPn7N4NBZP6TyN8EMtc= + + PlugIns/PIA VPN AdBlocker.appex/PIA VPN AdBlocker + + OKEPnwacmaBAKkB7rVCPCDOR9c8= + + PlugIns/PIA VPN AdBlocker.appex/_CodeSignature/CodeResources + + 9unv4ky0COWfhGTukXWJu3sCAe8= + + PlugIns/PIA VPN AdBlocker.appex/fallback.json + + o+Lo69t3mS7eXpQh0LOFlPTgDBY= + + PlugIns/PIA VPN Tunnel.appex/Info.plist + + koEREoV68vN8bCz5MLjXJ6u02jw= + + PlugIns/PIA VPN Tunnel.appex/PIA VPN Tunnel + + 6Ulfvewhy+dbNfrT88RxFpGwNlo= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Assets.car + + 8h6Hyf4U9/+JlpRmAN3vBaPEjrw= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Info.plist + + U4V2uvQAAIulAUfBSoJQTzWiVN4= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + dytHgVNc10hWhKQW+WIDasbWdTU= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib + + OVb1ASokoqm9FsqgYqS4ykOLvTk= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + qEnPzvZ7YJ2malb9v8b6uU1qRtI= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib + + BnH89TJFPy09hwlepgmy1qX8w5I= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist + + tvSnglTgEmfEVDs4Pqzq89zCWdk= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + htQTSxHbapTjr/KU4MZ+BReh+fg= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + CJa19sBIiRCsSpkmvlAK9WVgIUc= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib + + DClrKMNBhP7R57XPbVZNLZEkhHY= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib + + RII82MT1u8xiVhoF6z8GAPWRauw= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + YpRMevT/Hk92B7qxIoBZNubmhVo= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + bJ8pWQoqUwPJh2R449Z5iB80fgw= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + XIT4vTE0sbcaxPw4Ukcc10AudMU= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + 8QYAr5CSJVq9J2M/WNeKrHxyH4k= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + /KugdZ7rq/us89d7xS8Y4W80uoE= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + lAQN56rjGXobwkMhOfbs34FT+S8= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist + + /pYtZWavELI0+6nEkTUa0WNFSew= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + QLgeyu0ZVc/lDmyITQfrBSRT2Hk= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + gA8eOIpUQd1BEBgO/w9hDFS+JxU= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + GzhYGB3AyZ0wytBn61POuwdsJ7E= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + sQtUseVfpjT4CFtCBgvBwDjWfQA= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory + + gjf0PUSrcJskfjBJ7fSOp0hPRqU= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements + + OnX22wWFKRSOFN1+obRynMCeyXM= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 + + Xek7S2WT/EJTVDHjzmsxCQMBPMg= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources + + ypAPfIR7Xyk9v8RohL9v2uz3dB4= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature + + 2jmj7l5rSw0yVb/vlWAYkK/YBwk= + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings + + hash + + KDACaW+muq3Q7S2KFi/tSoBrOA0= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings + + hash + + q69blyRGQI14B9CBKT9Rsw4dq0k= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings + + hash + + BkACZwewt5pWHuYeiW8u/ttymCg= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings + + hash + + ImqHeuQyhd4vbb7tX6gDpc0Uws4= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/UI.strings + + hash + + JEB6TYMiWHIJ3Fwzv9hwS3X5B9c= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings + + hash + + 0U+OaxIpF3m54GcZw6Rj0FT9IQU= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings + + hash + + ULQLCKJ1Tkx5LYNqw+wZAPpz+fc= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/UI.strings + + hash + + 1964G9tW/vLUljfWDybLqmj8ovo= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings + + hash + + j/jLkt7lT5WaqzpSmS2HeZ2YT7g= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings + + hash + + EZ9QZ7PSibfcWSeEETK4rR/PkKE= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/UI.strings + + hash + + 8v4J37YS+jZq3LBvpRfFdfrmOjo= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings + + hash + + BwdYyKtC03avQBNFX31HfqSElzI= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings + + hash + + /cuvVUGtYOlubi9pgRpN8GF6eaQ= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings + + hash + + iiP5bcCQB5ClycQCkVGeHIMUAks= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings + + hash + + lx4/QzIqPJcVTvU4PUA9DuA+iR0= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings + + hash + + vRPh7xNvA8CBlDbvqId98Ppaol4= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings + + hash + + IbgvE2UN4PxyRd+exu9NKENUaI0= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings + + hash + + KoygslQ7+C06O61A0YHLMJPIhd8= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings + + hash + + Ed4oYGhilkGVvO6AshjBjzdE+7w= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/UI.strings + + hash + + Y50/iDsqGezjtBuqSlPo8jymMAc= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings + + hash + + 8OHVfUCzQp3y5Avt0qvL0KEijp8= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings + + hash + + nNEDjklKvB3EYDy3z/dKvk0Y3Sc= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings + + hash + + +2YIistydmlPjDts2u1ROqKtWqI= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings + + hash + + RbM1jidNxxT0GrCW5Bp4AJ2C10U= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings + + hash + + v+qEVshU1lPCEIX6p/5VNVvHCsE= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings + + hash + + XSewfIvou+2vfPzfd4L1JobLejU= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings + + hash + + j/ZhhE8EhAk/Lumf0d8hAl0mnM0= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings + + hash + + KhJ/QqRfNp4OZfzpif4GtcBF8bI= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings + + hash + + xDMWYimFFDfSHhe2YZpdtrl2g8k= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings + + hash + + uwWBmqf4ftnCEhc6CREp8ByROW4= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings + + hash + + NyXHmGW4hA/Eauh4ij9O5S5WhTA= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings + + hash + + YZpZdbu3r3xtH/jvKMalDSa3lOc= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings + + hash + + yqehLrthKrrux3wlT4BXD2o86VM= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings + + hash + + 6OMfwEOtzCuZV03uZytGep2fVcM= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings + + hash + + K6FfGb4sRyZ+8fUCnq80qKRGipc= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings + + hash + + jdPps229/rIXz+/ddHNG9FuKBhQ= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings + + hash + + fbM6TjAWhkqwQRqlFgXqxwrx+8k= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings + + hash + + 5JKfMEQAm3AUcBKlsob0yfJRkQk= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings + + hash + + 01ji1w1oANjR7h5TRr6cBlyaRGo= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings + + hash + + ZPLrICgFyE180EQFQQsAPW2T0LY= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings + + hash + + Ke55XO9cpqEQhKUHTr3HEvi0aUM= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings + + hash + + rfmjmvw733cPOhxZ0RizNQfXkSE= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings + + hash + + awJpWTrrqH31sd1t1ndiEy4cN/A= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/UI.strings + + hash + + QMaBIt1A8kjNOstov8L0lchT5Ec= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings + + hash + + 5J5E4i04UUqsWy3SQZN1zcKIZaQ= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings + + hash + + 55QLf0o5XG8IWfXbQ6KvFWToA+4= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings + + hash + + hfdFuAQLTfdHleeMkh4YCtlcNBY= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings + + hash + + R49azaTbZXexzZ4fO2KAO8IQIW4= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings + + hash + + B3OiNtJOoqFlNs77EeQh3/YlwiU= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings + + hash + + athEoNydnFVAkLxqKvlUTv5EfZg= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings + + hash + + 6aHDe64C6X+IcTDg3C39b+SM9Ls= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings + + hash + + InQh2yXFC6brp+xf2gtnVDZtsuY= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings + + hash + + 7NuRLJG/PUbRlsl/6dZTfboVNfQ= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings + + hash + + hBHKqa7nicnE6j15W8iBNQQdsws= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/Info.plist + + /Sr7lQ3v9dlVi0s0lsUfQz9dK84= + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem + + 3qHvNikZqOiKtbZEW5+oygpFyfw= + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA.der + + HjU73bSJKXFVdCTqzHVin0iWAak= + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory + + 1goWa+U5od4AnpP1zIi6N43ps+k= + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements + + OnX22wWFKRSOFN1+obRynMCeyXM= + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 + + ae4UnuV7lDFjF1toM8Tj2NbLvS4= + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources + + G9y6xZfvG8s3gN1rZw4IpRPNIIc= + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature + + 2jmj7l5rSw0yVb/vlWAYkK/YBwk= + + PlugIns/PIA VPN Tunnel.appex/_CodeSignature/CodeResources + + cOA+zJZk1JQ39Acbk2JJQ6QEimA= + + PlugIns/PIA VPN WG Tunnel.appex/Info.plist + + bCdKd9zhLFhkSgnfY1ayTtWs7BU= + + PlugIns/PIA VPN WG Tunnel.appex/PIA VPN WG Tunnel + + NA/CG0auVwWXApBz5NQnsQcKfhw= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Assets.car + + 8h6Hyf4U9/+JlpRmAN3vBaPEjrw= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Info.plist + + U4V2uvQAAIulAUfBSoJQTzWiVN4= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + dytHgVNc10hWhKQW+WIDasbWdTU= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib + + OVb1ASokoqm9FsqgYqS4ykOLvTk= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + qEnPzvZ7YJ2malb9v8b6uU1qRtI= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib + + BnH89TJFPy09hwlepgmy1qX8w5I= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist + + tvSnglTgEmfEVDs4Pqzq89zCWdk= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + htQTSxHbapTjr/KU4MZ+BReh+fg= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + CJa19sBIiRCsSpkmvlAK9WVgIUc= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib + + DClrKMNBhP7R57XPbVZNLZEkhHY= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib + + RII82MT1u8xiVhoF6z8GAPWRauw= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + YpRMevT/Hk92B7qxIoBZNubmhVo= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + bJ8pWQoqUwPJh2R449Z5iB80fgw= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + XIT4vTE0sbcaxPw4Ukcc10AudMU= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + 8QYAr5CSJVq9J2M/WNeKrHxyH4k= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + /KugdZ7rq/us89d7xS8Y4W80uoE= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + lAQN56rjGXobwkMhOfbs34FT+S8= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + g1+J6WekU+nhRJI25ngX0yAiaDU= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist + + /pYtZWavELI0+6nEkTUa0WNFSew= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + QLgeyu0ZVc/lDmyITQfrBSRT2Hk= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + gA8eOIpUQd1BEBgO/w9hDFS+JxU= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib + + 8mqSubnl0apcHTgaShRXf/8jWkc= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + sQmAdyaI2Yg7aJ7u96uxSEeTINA= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + 4sTJgjVzFNhe3umMU0wkhEkg3kg= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + F1TRVqwZx1/DGDHbIeYsMbK1pCs= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + mC3AMvZbnhEoE46cLLQj2h0b4ok= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + AiSqXXY6ZhA1WEFQmnxBsEZ3WnI= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + rRgX9LuIsWqBClxnVWJtrEStKXE= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + +N4Q5Ji9rSfrhfL1WipdNWJLm+Q= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + 427LqIUMWh5W6iViPTyHSRF1A6g= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + nDNRSB6cTESYBkV4jQ0on+SkxRg= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + GzhYGB3AyZ0wytBn61POuwdsJ7E= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + sQtUseVfpjT4CFtCBgvBwDjWfQA= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + E4fhR03Jj3b0lXRb1dTUVEqjbWg= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + zhqB1Z1OTrsU8jVpYTF4wCBZQ5E= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory + + gjf0PUSrcJskfjBJ7fSOp0hPRqU= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements + + OnX22wWFKRSOFN1+obRynMCeyXM= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 + + Xek7S2WT/EJTVDHjzmsxCQMBPMg= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources + + ypAPfIR7Xyk9v8RohL9v2uz3dB4= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature + + 2jmj7l5rSw0yVb/vlWAYkK/YBwk= + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings + + hash + + KDACaW+muq3Q7S2KFi/tSoBrOA0= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings + + hash + + q69blyRGQI14B9CBKT9Rsw4dq0k= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings + + hash + + BkACZwewt5pWHuYeiW8u/ttymCg= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings + + hash + + ImqHeuQyhd4vbb7tX6gDpc0Uws4= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/UI.strings + + hash + + JEB6TYMiWHIJ3Fwzv9hwS3X5B9c= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings + + hash + + 0U+OaxIpF3m54GcZw6Rj0FT9IQU= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings + + hash + + ULQLCKJ1Tkx5LYNqw+wZAPpz+fc= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/UI.strings + + hash + + 1964G9tW/vLUljfWDybLqmj8ovo= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings + + hash + + j/jLkt7lT5WaqzpSmS2HeZ2YT7g= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings + + hash + + EZ9QZ7PSibfcWSeEETK4rR/PkKE= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/UI.strings + + hash + + 8v4J37YS+jZq3LBvpRfFdfrmOjo= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings + + hash + + BwdYyKtC03avQBNFX31HfqSElzI= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings + + hash + + /cuvVUGtYOlubi9pgRpN8GF6eaQ= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings + + hash + + iiP5bcCQB5ClycQCkVGeHIMUAks= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings + + hash + + lx4/QzIqPJcVTvU4PUA9DuA+iR0= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings + + hash + + vRPh7xNvA8CBlDbvqId98Ppaol4= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings + + hash + + IbgvE2UN4PxyRd+exu9NKENUaI0= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings + + hash + + KoygslQ7+C06O61A0YHLMJPIhd8= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings + + hash + + Ed4oYGhilkGVvO6AshjBjzdE+7w= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/UI.strings + + hash + + Y50/iDsqGezjtBuqSlPo8jymMAc= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings + + hash + + 8OHVfUCzQp3y5Avt0qvL0KEijp8= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings + + hash + + nNEDjklKvB3EYDy3z/dKvk0Y3Sc= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings + + hash + + +2YIistydmlPjDts2u1ROqKtWqI= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings + + hash + + RbM1jidNxxT0GrCW5Bp4AJ2C10U= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings + + hash + + v+qEVshU1lPCEIX6p/5VNVvHCsE= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings + + hash + + XSewfIvou+2vfPzfd4L1JobLejU= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings + + hash + + j/ZhhE8EhAk/Lumf0d8hAl0mnM0= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings + + hash + + KhJ/QqRfNp4OZfzpif4GtcBF8bI= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings + + hash + + xDMWYimFFDfSHhe2YZpdtrl2g8k= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings + + hash + + uwWBmqf4ftnCEhc6CREp8ByROW4= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings + + hash + + NyXHmGW4hA/Eauh4ij9O5S5WhTA= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings + + hash + + YZpZdbu3r3xtH/jvKMalDSa3lOc= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings + + hash + + yqehLrthKrrux3wlT4BXD2o86VM= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings + + hash + + 6OMfwEOtzCuZV03uZytGep2fVcM= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings + + hash + + K6FfGb4sRyZ+8fUCnq80qKRGipc= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings + + hash + + jdPps229/rIXz+/ddHNG9FuKBhQ= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings + + hash + + fbM6TjAWhkqwQRqlFgXqxwrx+8k= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings + + hash + + 5JKfMEQAm3AUcBKlsob0yfJRkQk= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings + + hash + + 01ji1w1oANjR7h5TRr6cBlyaRGo= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings + + hash + + ZPLrICgFyE180EQFQQsAPW2T0LY= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings + + hash + + Ke55XO9cpqEQhKUHTr3HEvi0aUM= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings + + hash + + rfmjmvw733cPOhxZ0RizNQfXkSE= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings + + hash + + awJpWTrrqH31sd1t1ndiEy4cN/A= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/UI.strings + + hash + + QMaBIt1A8kjNOstov8L0lchT5Ec= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings + + hash + + 5J5E4i04UUqsWy3SQZN1zcKIZaQ= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings + + hash + + 55QLf0o5XG8IWfXbQ6KvFWToA+4= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings + + hash + + hfdFuAQLTfdHleeMkh4YCtlcNBY= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings + + hash + + R49azaTbZXexzZ4fO2KAO8IQIW4= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings + + hash + + B3OiNtJOoqFlNs77EeQh3/YlwiU= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings + + hash + + athEoNydnFVAkLxqKvlUTv5EfZg= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings + + hash + + 6aHDe64C6X+IcTDg3C39b+SM9Ls= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings + + hash + + InQh2yXFC6brp+xf2gtnVDZtsuY= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings + + hash + + 7NuRLJG/PUbRlsl/6dZTfboVNfQ= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings + + hash + + hBHKqa7nicnE6j15W8iBNQQdsws= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/Info.plist + + /Sr7lQ3v9dlVi0s0lsUfQz9dK84= + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem + + 3qHvNikZqOiKtbZEW5+oygpFyfw= + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA.der + + HjU73bSJKXFVdCTqzHVin0iWAak= + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory + + 1goWa+U5od4AnpP1zIi6N43ps+k= + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements + + OnX22wWFKRSOFN1+obRynMCeyXM= + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 + + ae4UnuV7lDFjF1toM8Tj2NbLvS4= + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources + + G9y6xZfvG8s3gN1rZw4IpRPNIIc= + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature + + 2jmj7l5rSw0yVb/vlWAYkK/YBwk= + + PlugIns/PIA VPN WG Tunnel.appex/_CodeSignature/CodeResources + + DM7c62VdUidYpZpAl8iPuvu2eeU= + + PlugIns/PIAWidgetExtension.appex/Assets.car + + vBNI4c3x6TEPyDIB9amVjE8MBJY= + + PlugIns/PIAWidgetExtension.appex/Base.lproj/PIAWidget.intentdefinition + + hash + + zKcNL89QiaANd0DXGfqWn47GOnk= + + optional + + + PlugIns/PIAWidgetExtension.appex/Info.plist + + fTJ7PehK4e2nU10GoLdOc+jfTr8= + + PlugIns/PIAWidgetExtension.appex/PIAWidgetExtension + + VLhra95kD3+Uc5cxCVRUjmQIuvw= + + PlugIns/PIAWidgetExtension.appex/_CodeSignature/CodeResources + + 8KHjfgXdcojxVLi8NfkNPSeEUgo= + + PlugIns/PIAWidgetExtension.appex/ar.lproj/Localizable.strings + + hash + + Md6QT7nIXXDk61r6o83jOaoWi+0= + + optional + + + PlugIns/PIAWidgetExtension.appex/da.lproj/Localizable.strings + + hash + + CTDN1XeuYiB1Dn4x9l3Cjn7SKv8= + + optional + + + PlugIns/PIAWidgetExtension.appex/de.lproj/Localizable.strings + + hash + + 8/nukEsYQ4vBEUDnlPSkyIjQ2DA= + + optional + + + PlugIns/PIAWidgetExtension.appex/en.lproj/Localizable.strings + + hash + + AJXWjNsRROlJEGZeFrb111WXA44= + + optional + + + PlugIns/PIAWidgetExtension.appex/es-MX.lproj/Localizable.strings + + hash + + +dHYJ81rLTFc7oKY3/pbEW2skUk= + + optional + + + PlugIns/PIAWidgetExtension.appex/fr.lproj/Localizable.strings + + hash + + 9Eefd/eagluOmcPRDhlxT3YuWfM= + + optional + + + PlugIns/PIAWidgetExtension.appex/it.lproj/Localizable.strings + + hash + + gynEJhQ4J0z8hbym4dAdsmwTksI= + + optional + + + PlugIns/PIAWidgetExtension.appex/ja.lproj/Localizable.strings + + hash + + 5GPLw4+YK+7mnET38TEEzhsKwYk= + + optional + + + PlugIns/PIAWidgetExtension.appex/ko.lproj/Localizable.strings + + hash + + mqm3uu4o2lIi8bzz58Ii/Rdi9oo= + + optional + + + PlugIns/PIAWidgetExtension.appex/nb.lproj/Localizable.strings + + hash + + BwL+yuRj49Rm6s6nM7nvnL+58W0= + + optional + + + PlugIns/PIAWidgetExtension.appex/nl.lproj/Localizable.strings + + hash + + fenhiY0m5ubSFhtYN+ro2CZaG28= + + optional + + + PlugIns/PIAWidgetExtension.appex/pl.lproj/Localizable.strings + + hash + + nBjLPFE5/KP+kmCGvxqF3bwczjI= + + optional + + + PlugIns/PIAWidgetExtension.appex/pt-BR.lproj/Localizable.strings + + hash + + dWPcM+tXr9hodLfIAwkNjectrBQ= + + optional + + + PlugIns/PIAWidgetExtension.appex/ru.lproj/Localizable.strings + + hash + + kAdbQQhGPzEm9H/X6buQTzv3u6w= + + optional + + + PlugIns/PIAWidgetExtension.appex/th.lproj/Localizable.strings + + hash + + rZJba2j4PMzgaYRjn1/bLJcTKzY= + + optional + + + PlugIns/PIAWidgetExtension.appex/tr.lproj/Localizable.strings + + hash + + +sGzQAimWS3xf7hW1Vr+7QtVHQk= + + optional + + + PlugIns/PIAWidgetExtension.appex/zh-Hans.lproj/Localizable.strings + + hash + + XHPmF5td4UsQ+XrYF6tNWQaM0QA= + + optional + + + PlugIns/PIAWidgetExtension.appex/zh-Hant.lproj/Localizable.strings + + hash + + Ry9RWHjEmPc/PwrKkrtt8PF+hiI= + + optional + + + QuickConnectTile.nib + + wvsI7/dWp7NQzcu0PjShqum2b6A= + + QuickConnectTileCollectionViewCell.nib/objects-12.3+.nib + + qBv7tv042QdPLcSUa5t2r0a/ri0= + + QuickConnectTileCollectionViewCell.nib/runtime.nib + + WJNjugLIIOpkANVlrkVIDsYCKDE= + + QuickSettingsTile.nib + + D06dKKLlAIrdGg4GRXC4GWhv97k= + + QuickSettingsTileCollectionViewCell.nib/objects-12.3+.nib + + TpbgdpvQrZo8g0Ocv7AL5gRMLfc= + + QuickSettingsTileCollectionViewCell.nib/runtime.nib + + QE5kvzzwwXJ5XbhR117PDuquPeE= + + RegionTile.nib + + aFgdt19dRnU4Nf/ZklPl9tJyUAo= + + RegionTileCollectionViewCell.nib/objects-12.3+.nib + + jujeE/nRFo7BO0CpiXfGgN4nSyY= + + RegionTileCollectionViewCell.nib/runtime.nib + + ogukkPx5nQh1eF+Elqf9MNVt5qE= + + Regions.json + + DJzO1F097fUespYf5s3j5x5/UWE= + + Roboto-Light.ttf + + c6K7LW5ZGpD/tO0RijmJ+xe1THs= + + Roboto-Medium.ttf + + Xxb01tu0pPEtiulkiKwgm7SXYqU= + + Roboto-Regular.ttf + + 3RsdsT/x9yE4wTTGLzj++DdJ82o= + + Roboto-Thin.ttf + + lRSteu40FZT0OjOJPws9im2B8y4= + + SubscriptionTile.nib + + UNWxuNxaM3h1YObXGhhiRSxkmwk= + + SubscriptionTileCollectionViewCell.nib/objects-12.3+.nib + + RHLnojCja4l9dQ7owywnLBFntgA= + + SubscriptionTileCollectionViewCell.nib/runtime.nib + + xAPCz3NMARZ+O1YoHN1YvWOPEak= + + UsageTile.nib + + fxkbxoiITETV3V7fLgmZO69Irc8= + + UsageTileCollectionViewCell.nib/objects-12.3+.nib + + 09Mf+YlgI7i2vTzCXdXPLEp5aqU= + + UsageTileCollectionViewCell.nib/runtime.nib + + 3SVR/mIgn1Ygs9G75ljeIc45T1w= + + ar.lproj/InfoPlist.strings + + hash + + eZCAeTvSZyIWN99v+N4+xGGl4P8= + + optional + + + ar.lproj/Localizable.strings + + hash + + Md6QT7nIXXDk61r6o83jOaoWi+0= + + optional + + + custom.servers + + rcg7GeeTSRscbqD9i0bNnzLlkvw= + + da.lproj/InfoPlist.strings + + hash + + mtgTd8H58OZaKytrXcsxCPD9HEQ= + + optional + + + da.lproj/Localizable.strings + + hash + + CTDN1XeuYiB1Dn4x9l3Cjn7SKv8= + + optional + + + de.lproj/InfoPlist.strings + + hash + + BzjtCCrxYzWf8h0GpNA7Pc2nWS4= + + optional + + + de.lproj/Localizable.strings + + hash + + 8/nukEsYQ4vBEUDnlPSkyIjQ2DA= + + optional + + + en.lproj/InfoPlist.strings + + hash + + uwgTyaeJC9ClFlhxJ+L+eRjBFqw= + + optional + + + en.lproj/Localizable.strings + + hash + + AJXWjNsRROlJEGZeFrb111WXA44= + + optional + + + en.lproj/Main.storyboardc/8GT-4Z-Eox-view-QZg-xz-wXy.nib + + hash + + 0j6aZGw6b+za6Esppy+Safn8+pE= + + optional + + + en.lproj/Main.storyboardc/BNo-Ag-Vl2-view-8tS-UG-dKk.nib + + hash + + xpV5TTuNHVCfw5Qq6f1S4EGml7M= + + optional + + + en.lproj/Main.storyboardc/BP1-69-boB-view-LKz-D5-KlE.nib + + hash + + ccPi6Wfok7kYhR21M+M0T2KsfiE= + + optional + + + en.lproj/Main.storyboardc/BcC-bW-Cr7-view-b9l-eX-dk8.nib + + hash + + xpV5TTuNHVCfw5Qq6f1S4EGml7M= + + optional + + + en.lproj/Main.storyboardc/CEm-fv-KfP-view-R8e-Ar-VG0.nib + + hash + + KOM5ptfD3HqKVEBI5RawBKi5cE4= + + optional + + + en.lproj/Main.storyboardc/ConfirmVPNPlanViewController.nib + + hash + + lyQwUPVXdsb/OMiAciOEc+niE9A= + + optional + + + en.lproj/Main.storyboardc/Info.plist + + hash + + qQOqa54Lxd55KNM6JQrNUo9ETt4= + + optional + + + en.lproj/Main.storyboardc/Jcq-Qm-xQ1-view-3ye-eb-yzU.nib + + hash + + WPvIe+wFyh9Iws456IAKxyf7P/M= + + optional + + + en.lproj/Main.storyboardc/LrP-0B-Ym4-view-R3h-W3-NNr.nib + + hash + + 5WtucemPyY+AUQCDG0LJT1BHxo8= + + optional + + + en.lproj/Main.storyboardc/Ltp-Dt-4e7-view-kgw-5Z-a7U.nib + + hash + + MGNvdPdWfhepPZP6hFyB6ACxx/w= + + optional + + + en.lproj/Main.storyboardc/MU8-v2-7Zn-view-Rsa-kn-TH2.nib + + hash + + O72HuKEe9Sm7ZHljaoWg9gCZgFQ= + + optional + + + en.lproj/Main.storyboardc/PIACardsViewController.nib + + hash + + BqYpqyepVjGuRw5O4n+ghznlHHw= + + optional + + + en.lproj/Main.storyboardc/PW2-xO-eP5-view-dN1-YI-Ruq.nib + + hash + + VKXGTznYb4epcbpufB9usHa3qyk= + + optional + + + en.lproj/Main.storyboardc/SAw-ll-7Hp-view-H9q-Rn-fdF.nib + + hash + + SfCU0+O77CZCzUuT5t3LR5h8Txo= + + optional + + + en.lproj/Main.storyboardc/SideMenuNavigationController.nib + + hash + + AJ0eTzUWcHzE6gdi+H+UdprsMgo= + + optional + + + en.lproj/Main.storyboardc/UINavigationController-GHB-bv-bDF.nib + + hash + + oOIfZltVxIdSsWaDzsjckrcutNQ= + + optional + + + en.lproj/Main.storyboardc/UINavigationController-boO-X9-UIe.nib + + hash + + J0t5Qsul4GyQjCEXVbqfKDg1hMo= + + optional + + + en.lproj/Main.storyboardc/UIViewController-BNo-Ag-Vl2.nib + + hash + + 10yeYY6hNmABNoT5vsKki4mEybM= + + optional + + + en.lproj/Main.storyboardc/UIViewController-BP1-69-boB.nib + + hash + + JrpqvVwIsZ1WJlJkKf0uEHQn8LI= + + optional + + + en.lproj/Main.storyboardc/UIViewController-BcC-bW-Cr7.nib + + hash + + oQUGC5oCJrGNRYRXZTiImfFN+Qo= + + optional + + + en.lproj/Main.storyboardc/UIViewController-LrP-0B-Ym4.nib + + hash + + /OEg9tfSG/taEhoadR38AV0xwT4= + + optional + + + en.lproj/Main.storyboardc/UIViewController-Ltp-Dt-4e7.nib + + hash + + x4AYaJxIBQ6QZ3VMx0IRYyNMByA= + + optional + + + en.lproj/Main.storyboardc/UIViewController-MU8-v2-7Zn.nib + + hash + + OsNe63nGzBKjV+VRilR+LtbumUQ= + + optional + + + en.lproj/Main.storyboardc/UIViewController-PW2-xO-eP5.nib + + hash + + oag0s9q6GaJE39CENbrPB1fXwR8= + + optional + + + en.lproj/Main.storyboardc/UIViewController-SAw-ll-7Hp.nib + + hash + + uanO+AB6BvjDDT/VZdQUADDfaLg= + + optional + + + en.lproj/Main.storyboardc/UIViewController-W4F-zm-KqY.nib + + hash + + bKRdIgKzieYFXLQ1sSgRwRV25v4= + + optional + + + en.lproj/Main.storyboardc/UIViewController-ckY-cv-bTr.nib + + hash + + 9Bb1oGKwVDsszi+D6c21dCbFmyc= + + optional + + + en.lproj/Main.storyboardc/UIViewController-dAM-Z5-oAd.nib + + hash + + 7iuPDGWGY5AQazl8P3kbaf5f0ss= + + optional + + + en.lproj/Main.storyboardc/UIViewController-dQc-D3-32b.nib + + hash + + LSM09oOIB2p/uIzcat1Brs4p8Mk= + + optional + + + en.lproj/Main.storyboardc/UIViewController-eBS-0e-zkL.nib + + hash + + C9fI5L9qXGqsuVmfddmBJ439sZ4= + + optional + + + en.lproj/Main.storyboardc/UIViewController-jy7-91-daJ.nib + + hash + + AB0ZUxXSExfijtgHv6emgLqsPPU= + + optional + + + en.lproj/Main.storyboardc/UIViewController-rTx-sq-4Hq.nib + + hash + + urDAcPxPnwQFCJ2fXmEUi4CKvBE= + + optional + + + en.lproj/Main.storyboardc/UIViewController-tRS-0y-Z0e.nib + + hash + + f8TpTzdX3o3su1orynCo3OZRd9E= + + optional + + + en.lproj/Main.storyboardc/UIViewController-uom-Te-eRI.nib + + hash + + XIIo87Yrm5BQ/2es23lhB/9kBNw= + + optional + + + en.lproj/Main.storyboardc/UIViewController-ytC-cJ-8NL.nib + + hash + + 8QvkLd6NN7GHrm0gOqs+uBaEQdw= + + optional + + + en.lproj/Main.storyboardc/VPNPermissionViewController.nib + + hash + + QLVMIahAAoU7jNt3LHzsQu2RIcQ= + + optional + + + en.lproj/Main.storyboardc/W4F-zm-KqY-view-xbM-if-7h8.nib + + hash + + A6cdxI2DoTU0wEpNmZS9CyWiK3o= + + optional + + + en.lproj/Main.storyboardc/ckY-cv-bTr-view-VtZ-Wr-diD.nib + + hash + + wp3OR3rbWrxDGBxSsJB5IWUt24g= + + optional + + + en.lproj/Main.storyboardc/dAM-Z5-oAd-view-t5R-BN-3Wx.nib + + hash + + wuJ6FDmEW+QP1qMKvgumNLiQP5I= + + optional + + + en.lproj/Main.storyboardc/dQc-D3-32b-view-if1-76-vY3.nib + + hash + + xpV5TTuNHVCfw5Qq6f1S4EGml7M= + + optional + + + en.lproj/Main.storyboardc/eBS-0e-zkL-view-Ax3-s6-smO.nib + + hash + + xpV5TTuNHVCfw5Qq6f1S4EGml7M= + + optional + + + en.lproj/Main.storyboardc/fek-Xn-fRR-view-PEc-bc-lz4.nib + + hash + + 9k7zlL+kxJi5jBYhwDnLKIieBdE= + + optional + + + en.lproj/Main.storyboardc/fzy-5R-TDW-view-Enl-Vx-oZs.nib + + hash + + m0XEKwel7rLZaEoE5uVwGWWgQLQ= + + optional + + + en.lproj/Main.storyboardc/g6e-47-VJ0-view-Oy9-GF-TW7.nib + + hash + + mK/SHja0Hq13IIWrtsRnXH434E4= + + optional + + + en.lproj/Main.storyboardc/jy7-91-daJ-view-P5B-eT-Ius.nib + + hash + + jqGePfMYMi2wtDpjmq1YAeez2V8= + + optional + + + en.lproj/Main.storyboardc/rTx-sq-4Hq-view-jUh-De-KQu.nib + + hash + + SMPexwLhM9lV6sQK7cTIID2d3x0= + + optional + + + en.lproj/Main.storyboardc/tRS-0y-Z0e-view-5si-tE-vZl.nib + + hash + + xpV5TTuNHVCfw5Qq6f1S4EGml7M= + + optional + + + en.lproj/Main.storyboardc/uom-Te-eRI-view-ibw-l8-EcR.nib + + hash + + xpV5TTuNHVCfw5Qq6f1S4EGml7M= + + optional + + + en.lproj/Main.storyboardc/ytC-cJ-8NL-view-QFu-xx-xle.nib + + hash + + 1TK+HNL2QV6hRZW8aXlCf8r3VJ8= + + optional + + + es-MX.lproj/InfoPlist.strings + + hash + + QztMig4kOSAcW//nTq6ydbJfOS8= + + optional + + + es-MX.lproj/Localizable.strings + + hash + + +dHYJ81rLTFc7oKY3/pbEW2skUk= + + optional + + + fr.lproj/InfoPlist.strings + + hash + + xdtNsC+hpJmsx/OqoCPGI1HEC6I= + + optional + + + fr.lproj/Localizable.strings + + hash + + 9Eefd/eagluOmcPRDhlxT3YuWfM= + + optional + + + it.lproj/InfoPlist.strings + + hash + + hOB1eL64wbi4dWXFc8bON5yfjYI= + + optional + + + it.lproj/Localizable.strings + + hash + + gynEJhQ4J0z8hbym4dAdsmwTksI= + + optional + + + ja.lproj/InfoPlist.strings + + hash + + OxSYf7V7xN3apSywCyPB0P3bOFg= + + optional + + + ja.lproj/Localizable.strings + + hash + + 5GPLw4+YK+7mnET38TEEzhsKwYk= + + optional + + + ko.lproj/InfoPlist.strings + + hash + + I7RLdDJGbYMeGkV7EUAi4XvmnDM= + + optional + + + ko.lproj/Localizable.strings + + hash + + mqm3uu4o2lIi8bzz58Ii/Rdi9oo= + + optional + + + nb.lproj/InfoPlist.strings + + hash + + LtGk8xWgcA28C00wkh7D7Yt549Q= + + optional + + + nb.lproj/Localizable.strings + + hash + + BwL+yuRj49Rm6s6nM7nvnL+58W0= + + optional + + + nl.lproj/InfoPlist.strings + + hash + + qkisgFD8oejG3I6Bn+WqQDAkDGM= + + optional + + + nl.lproj/Localizable.strings + + hash + + fenhiY0m5ubSFhtYN+ro2CZaG28= + + optional + + + pia-spinner.json + + NCM1hgD4qk/Brr5SotcRaEazy/4= + + pl.lproj/InfoPlist.strings + + hash + + GCVVDyIeSLXBLAEzM8Inrc+azE8= + + optional + + + pl.lproj/Localizable.strings + + hash + + nBjLPFE5/KP+kmCGvxqF3bwczjI= + + optional + + + pt-BR.lproj/InfoPlist.strings + + hash + + R+9HrbqoXUJIeJ+pfiIOp9lsqG4= + + optional + + + pt-BR.lproj/Localizable.strings + + hash + + dWPcM+tXr9hodLfIAwkNjectrBQ= + + optional + + + ru.lproj/InfoPlist.strings + + hash + + s5Hb7zn28GKFNZ/OO+cWK68aNsw= + + optional + + + ru.lproj/Localizable.strings + + hash + + kAdbQQhGPzEm9H/X6buQTzv3u6w= + + optional + + + staging.endpoint + + rcg7GeeTSRscbqD9i0bNnzLlkvw= + + th.lproj/InfoPlist.strings + + hash + + iG3xASNGPws/df22aRFrXNqD1Cg= + + optional + + + th.lproj/Localizable.strings + + hash + + rZJba2j4PMzgaYRjn1/bLJcTKzY= + + optional + + + tr.lproj/InfoPlist.strings + + hash + + LMXreguHD6fJGsBhN+B9CVON+OQ= + + optional + + + tr.lproj/Localizable.strings + + hash + + +sGzQAimWS3xf7hW1Vr+7QtVHQk= + + optional + + + zh-Hans.lproj/InfoPlist.strings + + hash + + mFtIMjKkPF4ZtM5ow26sNJ+hksQ= + + optional + + + zh-Hans.lproj/Localizable.strings + + hash + + XHPmF5td4UsQ+XrYF6tNWQaM0QA= + + optional + + + zh-Hant.lproj/InfoPlist.strings + + hash + + z+DcElwQazMMxRHNaB3wD4V9m/I= + + optional + + + zh-Hant.lproj/Localizable.strings + + hash + + Ry9RWHjEmPc/PwrKkrtt8PF+hiI= + + optional + + + + files2 + + ActiveDedicatedIpHeaderViewCell.nib + + hash2 + + JzUfOjpERm7yeTT9vLDYBsjuL95GPOzAQkkJMMJlSeI= + + + AppIcon60x60@2x.png + + hash2 + + ANEayskEVgLB38zYe+155lrw9MQXCFqWRpd9WJ5EeOk= + + + AppIcon76x76@2x~ipad.png + + hash2 + + 395fzfTsAqK6RVFM5y4xidAOesN6nUGEA6ffqQYc5bA= + + + Assets.car + + hash2 + + hQHd1POb6SA17i9C3HgIzWp4LBN0KzDZvYfLmlqe8gk= + + + Components.plist + + hash2 + + zKLgsK/2AQ20N48rbXSN9UiYHUwCLiFl8OPBKomL7Y8= + + + ConnectionTile.nib + + hash2 + + lhjiOBCKucQANHjBeLJlqUP3K+GEncUP9drhYS0DKDY= + + + ConnectionTileCollectionViewCell.nib/objects-12.3+.nib + + hash2 + + PUHR6VgJARkFrzc1iSCB/Bk3jjFbWfjbjIrrqpjEIpo= + + + ConnectionTileCollectionViewCell.nib/runtime.nib + + hash2 + + KFm4o3ZSYL1/Ha6ox5A+yflvaSCRKSvSU22qhU9myi0= + + + CustomNetworkCollectionViewCell.nib/objects-12.3+.nib + + hash2 + + EhJaIOcjCVkWcFb4pMwj6Osqqbqdi5wfxA3agWXJddc= + + + CustomNetworkCollectionViewCell.nib/runtime.nib + + hash2 + + f6SmP75ok47I0YoaCHakNiAExwTN03SkaDc9JkAKYZM= + + + DNS.plist + + hash2 + + jSSeW3hqP2gmgDL3CvRRdr3UCidz1RH4YHzeHHaRSAE= + + + DedicatedIPTitleHeaderViewCell.nib + + hash2 + + qvDzPItNrEosqBeTt87oYnH1k0q5fmv9KBNMFV/2KtE= + + + DedicatedIpEmptyHeaderViewCell.nib + + hash2 + + Cj/VvS7MAGI9KVT5KsBcg6NU0aV7A0CPVBpQjCBUh1Q= + + + DedicatedIpRowViewCell.nib + + hash2 + + rjPvhcql8Y7hThQjru6INBm701hWZByAZQHTXYzKHDk= + + + FavoriteServersTile.nib + + hash2 + + iENLV5osZo5Uai/svCnlIYawOLZ/Z09j2ifkLLO1Sng= + + + FavoriteServersTileCollectionViewCell.nib/objects-12.3+.nib + + hash2 + + JqzmNCRzgprmCZ9mq9CfwcOgqnWRuH3GTAjcYww1q3s= + + + FavoriteServersTileCollectionViewCell.nib/runtime.nib + + hash2 + + jvid0YVWb7YjQv1otqBHsghxPPUVLcJNV7E/NlJLyJY= + + + Flags-dev.plist + + hash2 + + SYobozP+qAt3KfQnjAuwf0AxU8cZnKM3Giv7BBbMniA= + + + Frameworks/PIACSI.framework/Info.plist + + hash2 + + iE14sQUBAFSs8EXtoZay4RsWuZ4uc5H8VaqISU5W40k= + + + Frameworks/PIACSI.framework/PIACSI + + hash2 + + UYD/nvK4cdBWxV9uEqvE95JZgI2Hm/E5YtcvPq0ON+w= + + + Frameworks/PIACSI.framework/_CodeSignature/CodeResources + + hash2 + + lXg7vviJ9qCJ/vmW/zOWQ51Z0/Xk0Mqx1/eIoU8X9lw= + + + Frameworks/PIAKPI.framework/Info.plist + + hash2 + + vjuoWByW92p29XKed+IEq/GQjC/fKzWHLS/84jWpURU= + + + Frameworks/PIAKPI.framework/PIAKPI + + hash2 + + EIsr+MuwS1bz8WZgLX0F1yIHbWg3LpuqiPkZ0IJ5/4c= + + + Frameworks/PIAKPI.framework/_CodeSignature/CodeResources + + hash2 + + RoKYQXCSaQYrGwy+kZLH3GErikxEbPSpYUOUhr0iUKw= + + + Frameworks/PIARegions.framework/Info.plist + + hash2 + + TCqVw35ISLTs3ZvlDTVSgeK4tUCb6d2fHwT7Tgxw/RQ= + + + Frameworks/PIARegions.framework/PIARegions + + hash2 + + 2buXq+6kz66OlH/z9uKQTorEjCvxqHDmdFuhrOoHofQ= + + + Frameworks/PIARegions.framework/_CodeSignature/CodeResources + + hash2 + + bDm1JD638PMdQ6kaq8rfdC8D5Fp4iR/7L3xLkXc61OA= + + + Frameworks/account.framework/Info.plist + + hash2 + + 8JNsw7BBQD37vKQqzxw1xW5U7TQH9OxWnkPcfIfFjmA= + + + Frameworks/account.framework/_CodeSignature/CodeResources + + hash2 + + F1fDnTvzqgwS5Z9FQRonAU8MuRp9FcBPRzYF0h1kAQs= + + + Frameworks/account.framework/account + + hash2 + + /PLKrHOBz6lSBeTGfsJn4vaTvRFZ6ELkNjCM48xIv38= + + + Frameworks/openssl.framework/Info.plist + + hash2 + + YaXkbyR4sfv5nWmqMi7LVZ0Ya1CfvtzlIuqb2ljK8pw= + + + Frameworks/openssl.framework/_CodeSignature/CodeResources + + hash2 + + mZexgCaYTrQHtz2ZP+Qr5YE0LK68GnwAhe1udt7VY2A= + + + Frameworks/openssl.framework/openssl + + hash2 + + a34rAV/JcYAizilc91ydwxaQIuE4sPYbeiWXfK81F8M= + + + IPTile.nib + + hash2 + + geOEWkniNAzRX12UEc0cdTQz8CeLEaOyfSBSx9nq5Lg= + + + IPTileCollectionViewCell.nib/objects-12.3+.nib + + hash2 + + 9K0QCcZgeaS+k0NSLCk1FNwu8h0XQAOPGVF0rRfymQs= + + + IPTileCollectionViewCell.nib/runtime.nib + + hash2 + + nmCYpilLkz7fjyVyUHbvLaQ6E61YzbHI3aW/6JLwyt8= + + + Launch Screen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib + + hash2 + + XskRzEDO3fNQDIxszpfL3izA5Jgos/IZG5/coMPJ3/0= + + + Launch Screen.storyboardc/Info.plist + + hash2 + + HyVdXMU7Ux4/KalAao30mpWOK/lEPT4gvYN09wf31cg= + + + Launch Screen.storyboardc/UIViewController-01J-lp-oVM.nib + + hash2 + + VPNjf2cf66XxnoLsT0p/tEi7PPwPsYDwiapXH8jwU+I= + + + MessagesTile.nib + + hash2 + + HyDrSJ/+2R4LJntxecDD93uXFUXFEhMZLPcRLiSbEz8= + + + MessagesTileCollectionViewCell.nib/objects-12.3+.nib + + hash2 + + ZSaHaAXwSQBk+On70b1RGtCJ+u+iVdvZiAxMJiEqHf4= + + + MessagesTileCollectionViewCell.nib/runtime.nib + + hash2 + + LlAwhTVZAoRtrs616J/eYilBmXMPCNUdBuCZnqPA4Sk= + + + NetworkCollectionViewCell.nib/objects-12.3+.nib + + hash2 + + pz6om0Lr75txal2Q6LHQS8OMcyIAQWXzUlrinEflXZg= + + + NetworkCollectionViewCell.nib/runtime.nib + + hash2 + + LH7CDmihAwO5/X8eJS8ovdFXHGM7/PlVxHThqqrmK4Y= + + + NetworkFooterCollectionViewCell.nib/objects-12.3+.nib + + hash2 + + 8ezozeq8qIMcfJBAhggEhmn5DQTMQ9j5gZUOomfZfvo= + + + NetworkFooterCollectionViewCell.nib/runtime.nib + + hash2 + + lCnKHQ3RlJ7tgBVkuf/vI3jJ4dUoRyXrVijeEI5ws6o= + + + PIA-RSA-4096.pem + + hash2 + + Mumx0UM+qXYU8qFMbjWOP1fAVwzJ9rLugSaZumlsZqs= + + + PIACard.nib + + hash2 + + bn6F+hcOOvVjaMVR/dOUlHAINGyNTu/mEOcnjoRto6c= + + + PIAHeaderCollectionViewCell.nib/objects-12.3+.nib + + hash2 + + mmVgNyCxOw6CyhXmyVEiBP7f7UhKtQcuIllfkAd1bIg= + + + PIAHeaderCollectionViewCell.nib/runtime.nib + + hash2 + + 94jjbuUiC3v7BYjwd1+tZfuwfAqpJfov5aL6Sj94rc8= + + + PIALibrary_PIALibrary.bundle/Assets.car + + hash2 + + z2oHVz8/itmR3oqHY51lv6NTMX9epuIIiBsUG+B3f3M= + + + PIALibrary_PIALibrary.bundle/Info.plist + + hash2 + + WFu/u2EPoebomnmaiyenOb8Mi4SrKw4owMy0mxtgPuY= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + hash2 + + EHhu+ZyC8bLdGTREBf6He41YqGou0HpQDQ4u1t+B67c= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib + + hash2 + + Rr/ex+JnT00WjY8BTVZWRNqz/GfU4jaR3v03FmrukIA= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + hash2 + + fkNfOkKA9R7NGpPPFiVhuYQ2+AdSVeR9osgZyyAms58= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib + + hash2 + + hDcEgabY8XWIV+bMHjY9T2LEXhXGYAjSsL1LyHygu1A= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist + + hash2 + + +ULlbQDKRqZAgLPRQ4aWV271svAlSIpTvPj8fAxklSA= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + hash2 + + vqbeJEql0Jgydj1T24xy6xJbrXkBGPmYusMqnTCSGcM= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + hash2 + + 28vreA7cNtWCBn0Hh2oGxsleKe0mqFxApasYvvlSWTo= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib + + hash2 + + FLZ/2WLEaK53aWKIJqX9T7ltNA15ERKTr7oZHeg14vU= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib + + hash2 + + 7XhIk/s4X/sIr5xEWP1PVGI7EV+vDS5HktrZ/OskXUk= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + hash2 + + N91d6/YhJJHCGX6EQSKWaoeSLBzL4sitnyKgo7IerzU= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + hash2 + + LmfITndcyawR5vC3q1+ZA3Tmezvc/H/UOm9eNi8rkXQ= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + hash2 + + cxj3iSMzDtgAEjJCn2Kh4wOxq643eP+NVKmuyRy4ScE= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + hash2 + + +pb1yeNeVETkzR3D7bHHd7b/7ckHANG2FYkou4fexeA= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + hash2 + + LcuEIHcg/ABNnzlBcFJUh1QnZG6OeeODUinCRME6gVM= + + + PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + hash2 + + 2sqAv9sKlmNLJyLvObb9ssgf6q3St0BYeyc41iKo10w= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist + + hash2 + + Y3Hpojl68zniB+aUL9PZXEVKtWuzsnlbS5/xAZKFhAo= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + hash2 + + rvJVcZPH3KzWKHiwzq/TcFc5ZloThq9gqavWaC6uX0s= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + hash2 + + 7V3P3q8VYMDAWwvrjqD85I4/kwFbGlegJ76JkMn8sDc= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + hash2 + + ZXVhR7A3IzlBTiK3AT8wLUDQeJhM59ywT6AJJWSHNuE= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + hash2 + + gE07Q/56h7roPAuaRZhMhxJ+wNhM0gvRduQ2/Him9z8= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory + + hash2 + + okxh/GX6INtaXI5mCHxoHTTaQyHkvI6ouJ+gLzrnNDE= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements + + hash2 + + mHkgkE6rZQ51eIwFSqCwUk5qgL/HGqMt+NI3phdD+YY= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 + + hash2 + + lLcvw56pfEheqGNbi4m/Vp+O5ghlDPZzLW3I4aJ+Y/o= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources + + hash2 + + klaP6QnT3PPiOIqDEsVyy6EZJohkwril3bMp1OxL7PA= + + + PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature + + hash2 + + 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= + + + PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings + + hash2 + + /PdaPdFVdwwWy0WMwLSdWCQv9CkI1tpm2JyG/6Tmn9M= + + optional + + + PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings + + hash2 + + YhKnZ6a5ITfwAgnv/6Cd1x+TPQ067/rO+K+rWNEzD6w= + + optional + + + PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings + + hash2 + + S1/lODt2iX9EyVMvBt0dsAV6rYE8BdXAlCaTa1+HTsw= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings + + hash2 + + +bSgSn+Mt62wraeSALDwHwkp4db5Q4ig2thAObbQPnc= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/UI.strings + + hash2 + + doJ3NS9+wFy5hCKe75hwGTA8tafBSrCQJnnrwcghQQs= + + optional + + + PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings + + hash2 + + udZzYVGokipS7z20EPQUqoeoTxmet5LGclYicXo/Qzc= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings + + hash2 + + 3qf/FrW+/u8t/lO9wA/+NtfCBtCJ1WguXGz2uvwUoc0= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/UI.strings + + hash2 + + OqXvZaKPjVRbECIamvYeVtO1k5SXy41xBrfoDBODJzU= + + optional + + + PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings + + hash2 + + /RCU9b12hOYxRv0uKqNRMyGNoOs2qGmTkLw0Js7xFcQ= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings + + hash2 + + eTcLQYTr4H9oZFv0rxYaq3gQ+WhpLjFnSyzwaOIiehc= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/UI.strings + + hash2 + + 2LmfTdHJMvlivEZbaU9xSJAAnvlpBpvBa+WumfJ+Zbs= + + optional + + + PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings + + hash2 + + oAZWhsRhLpQkW9ZhuKf4MOb41w5Y8MZPZx3S0NMM5tk= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings + + hash2 + + nI1MegvByIjofRyKN8F43cuCTWoXr5uIExtoQ3BK6NM= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings + + hash2 + + a8Vp2K22QfOvNgn1DCjRhoTHkZVdwywOmftje9rC42Y= + + optional + + + PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings + + hash2 + + mxe8YvU0Z6ToCEE2d86cOJNrmOVz8cRCJpBzDQWLVWc= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings + + hash2 + + QqrxBLWpNYv5rrqBFN8BLC6LNXUmQVa74Gl+0ksKBZU= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings + + hash2 + + Pv8eZpPXvR5mqm53bwD8agrzEaWy3xj6YdWgIOflm+M= + + optional + + + PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings + + hash2 + + xyVMkl7jhNBZ/vN0ZFmM2FlY8ovTdbitINQqEgRyqks= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings + + hash2 + + VlWjS5dJ4UNfaNhHqlxeKfkECiko5YzTss4+zOmzYJ4= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/UI.strings + + hash2 + + y2JDFhY4F9hvHbr4F4pF6PrFuy4JUyVFpMw8BcbSBY4= + + optional + + + PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings + + hash2 + + lu+ZwHtxRo9m+9fmCbojh8YbdagKuR6eYwXH/O4QNHo= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings + + hash2 + + bDq3nM4T1ut8Ts8+QYkxdWNGRu+//zSf189mi3aRlQ8= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings + + hash2 + + YaeZ3JgOA+qIusYRqxxG6pwBkrFim1rw7qTyLnl060I= + + optional + + + PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings + + hash2 + + Xq2cl5IrUxxaYjKRRxrCcWp8u2KzQtjBAPMG2ywwICA= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings + + hash2 + + tGa6ibOVYp6N7/L++jdOleoT9KE1QQ1PK1rhzpVOKDQ= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings + + hash2 + + QIUwyVItXRoQKXGmgHFFotXmiOSE9JxkZlaoE2IHX+8= + + optional + + + PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings + + hash2 + + weQQxyn+b2SpWKeGAvJqE/ii7MCRaDRxNADg8r9TvYI= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings + + hash2 + + RnLEv00iw5lOIGL/XJzJU1ShBwn9hBnC4hNhikuyhA4= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings + + hash2 + + CbdEeBsje8P4+h3x6IQ57ZROUQ898FBunnH3ZY69DnQ= + + optional + + + PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings + + hash2 + + 3l4+0NbmewoK9l0/qdkIGPcqqrLIRM5eOrwPHGkUEy0= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings + + hash2 + + VfV2uL8OKA5ZiR3yiHFT65ZEHaCbkn35Yo+ur18Bqxw= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings + + hash2 + + 69DUk8Zeh5SReiVA+Wk9iHozzU98pp8V8uFeG+EA+A0= + + optional + + + PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings + + hash2 + + LHqIVFxiS7xOGRDl+Mc94nzpdWHZpV7V+YNrcO3F6rw= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings + + hash2 + + me1r0CSvQxGrjhri1zbZY30vF6XWxdoV5q/XNHlGVhs= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings + + hash2 + + frs+aVxqmI1A7qNQ3lTqmaN+e68SScT1D6TutOPSHFs= + + optional + + + PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings + + hash2 + + xQJW7uzg6y9kJf1gLZnCM9oO+0wQ84AayU+o+TV5Y2I= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings + + hash2 + + MnV7VMLXWFm/KNE5a8UHkxR04f0OznpqoK1+9hyw8zY= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings + + hash2 + + DxvjdPIJCkbOywZjS5+ayQkGKWHlrGcquTxizAdezyg= + + optional + + + PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings + + hash2 + + LDC5bZkG2h8AgTQLoL1yMj6JJA/ir2Qs9YoX0A27QLc= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings + + hash2 + + WWOM/zJIvlgQASAWOk/VrhJ76xkmJSNIM383qyAebmY= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings + + hash2 + + oSkpUWDyzNoWL+/tE+JqlzA0l5XGRGrg0sa5Gvpc4eA= + + optional + + + PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings + + hash2 + + NeG7RvpFs7aBDoclE4CeSnfGf9AS7tGvjGr/m1zT3eY= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings + + hash2 + + buuAYnSRdzIW7wnFAfyIoc2xNnPeH6VmMpaTl1UnDcI= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/UI.strings + + hash2 + + 86j7ej1K8vjK2Wc+4VvI8COo0F5VNrFgab6jFb52UQM= + + optional + + + PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings + + hash2 + + CWB5kJ7tdPh65LpMEk7ON91tZXYPjCLHG3+KYt/Wor8= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings + + hash2 + + J7rTcADNQWVMdE7ToyJl5ztWFP7nS0LpgiIcVb4D/H8= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings + + hash2 + + mn9KO/anRw5JkawqXZT06MvC8pSCiTjPxNb+c3RrZ1I= + + optional + + + PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings + + hash2 + + 3U8T+edoinqQskEd4Y8vg0sVEFsjDRp4YCrhcTIq0Nw= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings + + hash2 + + 92+yGo0u+BgXiVmoYH9vE1wxCXffUp20Eb5V8JkLJDU= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings + + hash2 + + iDsYoUTxx8POedODQmaipEBJukmHm0klpri/JSYxzCg= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings + + hash2 + + NtHmRVKzAicr7H8AVAqK8Bni236Z2cMnLjdcG/U7T6M= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings + + hash2 + + ajON8rkioyflp0u9oIDFniyq4zryBG0tC/51c7OOzbY= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings + + hash2 + + IvX18xiU0gageVb9uJLXqnoj5htrqNqSWI1LCqnTWY0= + + optional + + + PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings + + hash2 + + E7PBBBbQdDJESlMtJW1vcQ17At7XbJBTHK0Mbm0eyU0= + + optional + + + PIAWireguard_PIAWireguard.bundle/Info.plist + + hash2 + + mwC94dBByVRThcNBnzQ+IGHCLsHQKv9SdkUi4cOLyI4= + + + PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem + + hash2 + + Mumx0UM+qXYU8qFMbjWOP1fAVwzJ9rLugSaZumlsZqs= + + + PIAWireguard_PIAWireguard.bundle/PIA.der + + hash2 + + H9JWWEVuqzBB+6d8zTmKuBJO3MG4svwdVf32sbv8nXA= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory + + hash2 + + 0YGO8yzUacVLcwaChXyFEDV700SjEoA3y4jHNuxE/nQ= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements + + hash2 + + mHkgkE6rZQ51eIwFSqCwUk5qgL/HGqMt+NI3phdD+YY= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 + + hash2 + + tlUOZy9wXXkJrqlFG78GXGAwhg6PtVrzl/M9S9NNm64= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources + + hash2 + + JoxbI6Yk1SD3A2j4qcD82qxRn61PU0HoJwlTobmuafE= + + + PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature + + hash2 + + 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= + + + PlugIns/PIA VPN AdBlocker.appex/Info.plist + + hash2 + + dTM2rBWInaGAbcRr0+qObrTIeLYKm5kc6fNjDjF8HK8= + + + PlugIns/PIA VPN AdBlocker.appex/PIA VPN AdBlocker + + hash2 + + SaR4X2P4HH+Z/FfK5z1ImLpl6KpOESCO7znv2kxJ8Os= + + + PlugIns/PIA VPN AdBlocker.appex/_CodeSignature/CodeResources + + hash2 + + IP3p81Wynl/krsEt15CFIsgSNfztVC8seKI1WXttGkE= + + + PlugIns/PIA VPN AdBlocker.appex/fallback.json + + hash2 + + JOhe7KOeAE1y+F2ln85wnQGyM5BSQSJNTtWeRveUyyE= + + + PlugIns/PIA VPN Tunnel.appex/Info.plist + + hash2 + + Flm8t78N0E8lmZQ62Y4nx7cpCoQvFW1LKR0FuTbzWCk= + + + PlugIns/PIA VPN Tunnel.appex/PIA VPN Tunnel + + hash2 + + uEnqJzkdh9vgVohThApfwyy+65BPJGlLRuo1egCsVXQ= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Assets.car + + hash2 + + z2oHVz8/itmR3oqHY51lv6NTMX9epuIIiBsUG+B3f3M= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Info.plist + + hash2 + + WFu/u2EPoebomnmaiyenOb8Mi4SrKw4owMy0mxtgPuY= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + hash2 + + EHhu+ZyC8bLdGTREBf6He41YqGou0HpQDQ4u1t+B67c= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib + + hash2 + + Rr/ex+JnT00WjY8BTVZWRNqz/GfU4jaR3v03FmrukIA= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + hash2 + + fkNfOkKA9R7NGpPPFiVhuYQ2+AdSVeR9osgZyyAms58= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib + + hash2 + + hDcEgabY8XWIV+bMHjY9T2LEXhXGYAjSsL1LyHygu1A= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist + + hash2 + + +ULlbQDKRqZAgLPRQ4aWV271svAlSIpTvPj8fAxklSA= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + hash2 + + vqbeJEql0Jgydj1T24xy6xJbrXkBGPmYusMqnTCSGcM= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + hash2 + + 28vreA7cNtWCBn0Hh2oGxsleKe0mqFxApasYvvlSWTo= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib + + hash2 + + FLZ/2WLEaK53aWKIJqX9T7ltNA15ERKTr7oZHeg14vU= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib + + hash2 + + 7XhIk/s4X/sIr5xEWP1PVGI7EV+vDS5HktrZ/OskXUk= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + hash2 + + N91d6/YhJJHCGX6EQSKWaoeSLBzL4sitnyKgo7IerzU= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + hash2 + + LmfITndcyawR5vC3q1+ZA3Tmezvc/H/UOm9eNi8rkXQ= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + hash2 + + cxj3iSMzDtgAEjJCn2Kh4wOxq643eP+NVKmuyRy4ScE= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + hash2 + + +pb1yeNeVETkzR3D7bHHd7b/7ckHANG2FYkou4fexeA= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + hash2 + + LcuEIHcg/ABNnzlBcFJUh1QnZG6OeeODUinCRME6gVM= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + hash2 + + 2sqAv9sKlmNLJyLvObb9ssgf6q3St0BYeyc41iKo10w= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist + + hash2 + + Y3Hpojl68zniB+aUL9PZXEVKtWuzsnlbS5/xAZKFhAo= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + hash2 + + rvJVcZPH3KzWKHiwzq/TcFc5ZloThq9gqavWaC6uX0s= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + hash2 + + 7V3P3q8VYMDAWwvrjqD85I4/kwFbGlegJ76JkMn8sDc= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + hash2 + + ZXVhR7A3IzlBTiK3AT8wLUDQeJhM59ywT6AJJWSHNuE= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + hash2 + + gE07Q/56h7roPAuaRZhMhxJ+wNhM0gvRduQ2/Him9z8= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory + + hash2 + + okxh/GX6INtaXI5mCHxoHTTaQyHkvI6ouJ+gLzrnNDE= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements + + hash2 + + mHkgkE6rZQ51eIwFSqCwUk5qgL/HGqMt+NI3phdD+YY= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 + + hash2 + + lLcvw56pfEheqGNbi4m/Vp+O5ghlDPZzLW3I4aJ+Y/o= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources + + hash2 + + klaP6QnT3PPiOIqDEsVyy6EZJohkwril3bMp1OxL7PA= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature + + hash2 + + 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings + + hash2 + + /PdaPdFVdwwWy0WMwLSdWCQv9CkI1tpm2JyG/6Tmn9M= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings + + hash2 + + YhKnZ6a5ITfwAgnv/6Cd1x+TPQ067/rO+K+rWNEzD6w= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings + + hash2 + + S1/lODt2iX9EyVMvBt0dsAV6rYE8BdXAlCaTa1+HTsw= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings + + hash2 + + +bSgSn+Mt62wraeSALDwHwkp4db5Q4ig2thAObbQPnc= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/UI.strings + + hash2 + + doJ3NS9+wFy5hCKe75hwGTA8tafBSrCQJnnrwcghQQs= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings + + hash2 + + udZzYVGokipS7z20EPQUqoeoTxmet5LGclYicXo/Qzc= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings + + hash2 + + 3qf/FrW+/u8t/lO9wA/+NtfCBtCJ1WguXGz2uvwUoc0= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/UI.strings + + hash2 + + OqXvZaKPjVRbECIamvYeVtO1k5SXy41xBrfoDBODJzU= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings + + hash2 + + /RCU9b12hOYxRv0uKqNRMyGNoOs2qGmTkLw0Js7xFcQ= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings + + hash2 + + eTcLQYTr4H9oZFv0rxYaq3gQ+WhpLjFnSyzwaOIiehc= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/UI.strings + + hash2 + + 2LmfTdHJMvlivEZbaU9xSJAAnvlpBpvBa+WumfJ+Zbs= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings + + hash2 + + oAZWhsRhLpQkW9ZhuKf4MOb41w5Y8MZPZx3S0NMM5tk= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings + + hash2 + + nI1MegvByIjofRyKN8F43cuCTWoXr5uIExtoQ3BK6NM= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings + + hash2 + + a8Vp2K22QfOvNgn1DCjRhoTHkZVdwywOmftje9rC42Y= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings + + hash2 + + mxe8YvU0Z6ToCEE2d86cOJNrmOVz8cRCJpBzDQWLVWc= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings + + hash2 + + QqrxBLWpNYv5rrqBFN8BLC6LNXUmQVa74Gl+0ksKBZU= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings + + hash2 + + Pv8eZpPXvR5mqm53bwD8agrzEaWy3xj6YdWgIOflm+M= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings + + hash2 + + xyVMkl7jhNBZ/vN0ZFmM2FlY8ovTdbitINQqEgRyqks= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings + + hash2 + + VlWjS5dJ4UNfaNhHqlxeKfkECiko5YzTss4+zOmzYJ4= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/UI.strings + + hash2 + + y2JDFhY4F9hvHbr4F4pF6PrFuy4JUyVFpMw8BcbSBY4= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings + + hash2 + + lu+ZwHtxRo9m+9fmCbojh8YbdagKuR6eYwXH/O4QNHo= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings + + hash2 + + bDq3nM4T1ut8Ts8+QYkxdWNGRu+//zSf189mi3aRlQ8= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings + + hash2 + + YaeZ3JgOA+qIusYRqxxG6pwBkrFim1rw7qTyLnl060I= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings + + hash2 + + Xq2cl5IrUxxaYjKRRxrCcWp8u2KzQtjBAPMG2ywwICA= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings + + hash2 + + tGa6ibOVYp6N7/L++jdOleoT9KE1QQ1PK1rhzpVOKDQ= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings + + hash2 + + QIUwyVItXRoQKXGmgHFFotXmiOSE9JxkZlaoE2IHX+8= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings + + hash2 + + weQQxyn+b2SpWKeGAvJqE/ii7MCRaDRxNADg8r9TvYI= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings + + hash2 + + RnLEv00iw5lOIGL/XJzJU1ShBwn9hBnC4hNhikuyhA4= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings + + hash2 + + CbdEeBsje8P4+h3x6IQ57ZROUQ898FBunnH3ZY69DnQ= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings + + hash2 + + 3l4+0NbmewoK9l0/qdkIGPcqqrLIRM5eOrwPHGkUEy0= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings + + hash2 + + VfV2uL8OKA5ZiR3yiHFT65ZEHaCbkn35Yo+ur18Bqxw= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings + + hash2 + + 69DUk8Zeh5SReiVA+Wk9iHozzU98pp8V8uFeG+EA+A0= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings + + hash2 + + LHqIVFxiS7xOGRDl+Mc94nzpdWHZpV7V+YNrcO3F6rw= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings + + hash2 + + me1r0CSvQxGrjhri1zbZY30vF6XWxdoV5q/XNHlGVhs= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings + + hash2 + + frs+aVxqmI1A7qNQ3lTqmaN+e68SScT1D6TutOPSHFs= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings + + hash2 + + xQJW7uzg6y9kJf1gLZnCM9oO+0wQ84AayU+o+TV5Y2I= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings + + hash2 + + MnV7VMLXWFm/KNE5a8UHkxR04f0OznpqoK1+9hyw8zY= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings + + hash2 + + DxvjdPIJCkbOywZjS5+ayQkGKWHlrGcquTxizAdezyg= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings + + hash2 + + LDC5bZkG2h8AgTQLoL1yMj6JJA/ir2Qs9YoX0A27QLc= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings + + hash2 + + WWOM/zJIvlgQASAWOk/VrhJ76xkmJSNIM383qyAebmY= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings + + hash2 + + oSkpUWDyzNoWL+/tE+JqlzA0l5XGRGrg0sa5Gvpc4eA= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings + + hash2 + + NeG7RvpFs7aBDoclE4CeSnfGf9AS7tGvjGr/m1zT3eY= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings + + hash2 + + buuAYnSRdzIW7wnFAfyIoc2xNnPeH6VmMpaTl1UnDcI= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/UI.strings + + hash2 + + 86j7ej1K8vjK2Wc+4VvI8COo0F5VNrFgab6jFb52UQM= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings + + hash2 + + CWB5kJ7tdPh65LpMEk7ON91tZXYPjCLHG3+KYt/Wor8= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings + + hash2 + + J7rTcADNQWVMdE7ToyJl5ztWFP7nS0LpgiIcVb4D/H8= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings + + hash2 + + mn9KO/anRw5JkawqXZT06MvC8pSCiTjPxNb+c3RrZ1I= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings + + hash2 + + 3U8T+edoinqQskEd4Y8vg0sVEFsjDRp4YCrhcTIq0Nw= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings + + hash2 + + 92+yGo0u+BgXiVmoYH9vE1wxCXffUp20Eb5V8JkLJDU= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings + + hash2 + + iDsYoUTxx8POedODQmaipEBJukmHm0klpri/JSYxzCg= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings + + hash2 + + NtHmRVKzAicr7H8AVAqK8Bni236Z2cMnLjdcG/U7T6M= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings + + hash2 + + ajON8rkioyflp0u9oIDFniyq4zryBG0tC/51c7OOzbY= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings + + hash2 + + IvX18xiU0gageVb9uJLXqnoj5htrqNqSWI1LCqnTWY0= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings + + hash2 + + E7PBBBbQdDJESlMtJW1vcQ17At7XbJBTHK0Mbm0eyU0= + + optional + + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/Info.plist + + hash2 + + mwC94dBByVRThcNBnzQ+IGHCLsHQKv9SdkUi4cOLyI4= + + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem + + hash2 + + Mumx0UM+qXYU8qFMbjWOP1fAVwzJ9rLugSaZumlsZqs= + + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA.der + + hash2 + + H9JWWEVuqzBB+6d8zTmKuBJO3MG4svwdVf32sbv8nXA= + + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory + + hash2 + + 0YGO8yzUacVLcwaChXyFEDV700SjEoA3y4jHNuxE/nQ= + + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements + + hash2 + + mHkgkE6rZQ51eIwFSqCwUk5qgL/HGqMt+NI3phdD+YY= + + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 + + hash2 + + tlUOZy9wXXkJrqlFG78GXGAwhg6PtVrzl/M9S9NNm64= + + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources + + hash2 + + JoxbI6Yk1SD3A2j4qcD82qxRn61PU0HoJwlTobmuafE= + + + PlugIns/PIA VPN Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature + + hash2 + + 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= + + + PlugIns/PIA VPN Tunnel.appex/_CodeSignature/CodeResources + + hash2 + + II/gYKsnEUcJXnjyxpGH6wTXqnL/6EhDmoCUWGdO8NY= + + + PlugIns/PIA VPN WG Tunnel.appex/Info.plist + + hash2 + + najGM0BQxC6AprY6ZTzYBvj/YhWEEvRItSxYlryo+7k= + + + PlugIns/PIA VPN WG Tunnel.appex/PIA VPN WG Tunnel + + hash2 + + wgQsmQf2R5107Izv5Xbn27JFnOLg0OR0oQokU5AcPaU= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Assets.car + + hash2 + + z2oHVz8/itmR3oqHY51lv6NTMX9epuIIiBsUG+B3f3M= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Info.plist + + hash2 + + WFu/u2EPoebomnmaiyenOb8Mi4SrKw4owMy0mxtgPuY= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/6bm-eY-LuK-view-VWt-1O-nc0.nib + + hash2 + + EHhu+ZyC8bLdGTREBf6He41YqGou0HpQDQ4u1t+B67c= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ConfirmVPNPlanViewController.nib + + hash2 + + Rr/ex+JnT00WjY8BTVZWRNqz/GfU4jaR3v03FmrukIA= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/EOm-5g-8UI-view-cqO-er-OWx.nib + + hash2 + + fkNfOkKA9R7NGpPPFiVhuYQ2+AdSVeR9osgZyyAms58= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/GDPRViewController.nib + + hash2 + + hDcEgabY8XWIV+bMHjY9T2LEXhXGYAjSsL1LyHygu1A= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Info.plist + + hash2 + + +ULlbQDKRqZAgLPRQ4aWV271svAlSIpTvPj8fAxklSA= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/MUM-1i-MG1-view-3IR-wb-vsm.nib + + hash2 + + vqbeJEql0Jgydj1T24xy6xJbrXkBGPmYusMqnTCSGcM= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/QNJ-sc-3YJ-view-QQw-C7-EBm.nib + + hash2 + + 28vreA7cNtWCBn0Hh2oGxsleKe0mqFxApasYvvlSWTo= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/ShareDataInformationViewController.nib + + hash2 + + FLZ/2WLEaK53aWKIJqX9T7ltNA15ERKTr7oZHeg14vU= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/SignupSuccessViewController.nib + + hash2 + + 7XhIk/s4X/sIr5xEWP1PVGI7EV+vDS5HktrZ/OskXUk= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UINavigationController-AJf-iF-18P.nib + + hash2 + + N91d6/YhJJHCGX6EQSKWaoeSLBzL4sitnyKgo7IerzU= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-MUM-1i-MG1.nib + + hash2 + + LmfITndcyawR5vC3q1+ZA3Tmezvc/H/UOm9eNi8rkXQ= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/UIViewController-y97-XZ-bVl.nib + + hash2 + + cxj3iSMzDtgAEjJCn2Kh4wOxq643eP+NVKmuyRy4ScE= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/Zr7-rl-bTc-view-r87-Ek-zal.nib + + hash2 + + +pb1yeNeVETkzR3D7bHHd7b/7ckHANG2FYkou4fexeA= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/vva-4H-w8I-view-VvQ-xl-mb4.nib + + hash2 + + LcuEIHcg/ABNnzlBcFJUh1QnZG6OeeODUinCRME6gVM= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Signup.storyboardc/y97-XZ-bVl-view-h2c-g8-ivh.nib + + hash2 + + 2sqAv9sKlmNLJyLvObb9ssgf6q3St0BYeyc41iKo10w= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/objects-12.3+.nib + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/GetStartedViewController.nib/runtime.nib + + hash2 + + kDVDbSUFFbbMJ7aQGaerVfEG2nW5dsOlw/HXMe8nTNg= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Info.plist + + hash2 + + Y3Hpojl68zniB+aUL9PZXEVKtWuzsnlbS5/xAZKFhAo= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/objects-12.3+.nib + + hash2 + + rvJVcZPH3KzWKHiwzq/TcFc5ZloThq9gqavWaC6uX0s= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/J5T-ys-Of8-view-hSf-Fj-o3R.nib/runtime.nib + + hash2 + + 7V3P3q8VYMDAWwvrjqD85I4/kwFbGlegJ76JkMn8sDc= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/objects-12.3+.nib + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/LoginViewController.nib/runtime.nib + + hash2 + + Ia1gDPQZ1BoqrPQC7Rhd0J9Kn5iZ2PGjfIJa8+KEM28= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/objects-12.3+.nib + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/MagicLinkLoginViewController.nib/runtime.nib + + hash2 + + UMye2buJhDaaIRW/hgWvwRh4KhBVj5L/lB14qO6zGAE= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/objects-12.3+.nib + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PIAWelcomeViewController.nib/runtime.nib + + hash2 + + lgPTlePuucLsMF6D0IFdFljCQsVGNSco5LOaNMHJz1A= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/objects-12.3+.nib + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/PurchaseViewController.nib/runtime.nib + + hash2 + + 9he59AUACvlXPBFJCPOoSCU/2gicbRqwOkXE2oxA3fg= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/objects-12.3+.nib + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/RestoreSignupViewController.nib/runtime.nib + + hash2 + + 6j1UICnCwvDxZPNhIXTD9cf0sBEVKBN1o3XLUFbBEPE= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/objects-12.3+.nib + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UINavigationController-VHM-bG-giz.nib/runtime.nib + + hash2 + + 0u/1YEJ8u++RaWtkqeH3sIgc0apxkwVMPL2MqFsxvYA= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/objects-12.3+.nib + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIPageViewController-lku-HF-3OI.nib/runtime.nib + + hash2 + + dBB2xnWQ9FuXpQzLsaZmhxxXIgeMAZjUZJDmvtY6aAk= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/objects-12.3+.nib + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/UIViewController-9jt-8I-K8i.nib/runtime.nib + + hash2 + + B0OWYWIes+qsoF2suCsVQSaSF6AkZNnzrbwKCA/b7Eg= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/objects-12.3+.nib + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/VQu-uR-ebb-view-t3k-ob-dIM.nib/runtime.nib + + hash2 + + 2kSlBBiHeDvsfnPcbzuElkoxfECBfjjuJRg5XPM6wU4= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/objects-12.3+.nib + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/Y1W-Um-2lp-view-MO3-fL-T5Z.nib/runtime.nib + + hash2 + + TeKG8rD79wPwPR/soXRuJayaLdmn3DgIr9tHN365EEA= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/objects-12.3+.nib + + hash2 + + ZXVhR7A3IzlBTiK3AT8wLUDQeJhM59ywT6AJJWSHNuE= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/bfs-I2-X8H-view-tO9-0u-CbU.nib/runtime.nib + + hash2 + + gE07Q/56h7roPAuaRZhMhxJ+wNhM0gvRduQ2/Him9z8= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/objects-12.3+.nib + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/gOX-c2-oGJ-view-m1d-km-gdB.nib/runtime.nib + + hash2 + + oQFc1xo7yts4QVvZ3EMdiDM/oMWK31VNOtPcy5yC6eg= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/objects-12.3+.nib + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/Welcome.storyboardc/vXZ-lx-hvc-view-kh9-bI-dsS.nib/runtime.nib + + hash2 + + V/FkbGBAMoCketD78ZxF5yQTTRAh46pu+Xw+zhABXFI= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeDirectory + + hash2 + + okxh/GX6INtaXI5mCHxoHTTaQyHkvI6ouJ+gLzrnNDE= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements + + hash2 + + mHkgkE6rZQ51eIwFSqCwUk5qgL/HGqMt+NI3phdD+YY= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeRequirements-1 + + hash2 + + lLcvw56pfEheqGNbi4m/Vp+O5ghlDPZzLW3I4aJ+Y/o= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeResources + + hash2 + + klaP6QnT3PPiOIqDEsVyy6EZJohkwril3bMp1OxL7PA= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/_CodeSignature/CodeSignature + + hash2 + + 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Signup.strings + + hash2 + + /PdaPdFVdwwWy0WMwLSdWCQv9CkI1tpm2JyG/6Tmn9M= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/UI.strings + + hash2 + + YhKnZ6a5ITfwAgnv/6Cd1x+TPQ067/rO+K+rWNEzD6w= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ar.lproj/Welcome.strings + + hash2 + + S1/lODt2iX9EyVMvBt0dsAV6rYE8BdXAlCaTa1+HTsw= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Signup.strings + + hash2 + + +bSgSn+Mt62wraeSALDwHwkp4db5Q4ig2thAObbQPnc= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/UI.strings + + hash2 + + doJ3NS9+wFy5hCKe75hwGTA8tafBSrCQJnnrwcghQQs= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/da.lproj/Welcome.strings + + hash2 + + udZzYVGokipS7z20EPQUqoeoTxmet5LGclYicXo/Qzc= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Signup.strings + + hash2 + + 3qf/FrW+/u8t/lO9wA/+NtfCBtCJ1WguXGz2uvwUoc0= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/UI.strings + + hash2 + + OqXvZaKPjVRbECIamvYeVtO1k5SXy41xBrfoDBODJzU= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/de.lproj/Welcome.strings + + hash2 + + /RCU9b12hOYxRv0uKqNRMyGNoOs2qGmTkLw0Js7xFcQ= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Signup.strings + + hash2 + + eTcLQYTr4H9oZFv0rxYaq3gQ+WhpLjFnSyzwaOIiehc= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/UI.strings + + hash2 + + 2LmfTdHJMvlivEZbaU9xSJAAnvlpBpvBa+WumfJ+Zbs= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/en.lproj/Welcome.strings + + hash2 + + oAZWhsRhLpQkW9ZhuKf4MOb41w5Y8MZPZx3S0NMM5tk= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Signup.strings + + hash2 + + nI1MegvByIjofRyKN8F43cuCTWoXr5uIExtoQ3BK6NM= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/UI.strings + + hash2 + + a8Vp2K22QfOvNgn1DCjRhoTHkZVdwywOmftje9rC42Y= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/es-MX.lproj/Welcome.strings + + hash2 + + mxe8YvU0Z6ToCEE2d86cOJNrmOVz8cRCJpBzDQWLVWc= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Signup.strings + + hash2 + + QqrxBLWpNYv5rrqBFN8BLC6LNXUmQVa74Gl+0ksKBZU= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/UI.strings + + hash2 + + Pv8eZpPXvR5mqm53bwD8agrzEaWy3xj6YdWgIOflm+M= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/fr.lproj/Welcome.strings + + hash2 + + xyVMkl7jhNBZ/vN0ZFmM2FlY8ovTdbitINQqEgRyqks= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Signup.strings + + hash2 + + VlWjS5dJ4UNfaNhHqlxeKfkECiko5YzTss4+zOmzYJ4= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/UI.strings + + hash2 + + y2JDFhY4F9hvHbr4F4pF6PrFuy4JUyVFpMw8BcbSBY4= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/it.lproj/Welcome.strings + + hash2 + + lu+ZwHtxRo9m+9fmCbojh8YbdagKuR6eYwXH/O4QNHo= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Signup.strings + + hash2 + + bDq3nM4T1ut8Ts8+QYkxdWNGRu+//zSf189mi3aRlQ8= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/UI.strings + + hash2 + + YaeZ3JgOA+qIusYRqxxG6pwBkrFim1rw7qTyLnl060I= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ja.lproj/Welcome.strings + + hash2 + + Xq2cl5IrUxxaYjKRRxrCcWp8u2KzQtjBAPMG2ywwICA= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Signup.strings + + hash2 + + tGa6ibOVYp6N7/L++jdOleoT9KE1QQ1PK1rhzpVOKDQ= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/UI.strings + + hash2 + + QIUwyVItXRoQKXGmgHFFotXmiOSE9JxkZlaoE2IHX+8= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ko.lproj/Welcome.strings + + hash2 + + weQQxyn+b2SpWKeGAvJqE/ii7MCRaDRxNADg8r9TvYI= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Signup.strings + + hash2 + + RnLEv00iw5lOIGL/XJzJU1ShBwn9hBnC4hNhikuyhA4= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/UI.strings + + hash2 + + CbdEeBsje8P4+h3x6IQ57ZROUQ898FBunnH3ZY69DnQ= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nb.lproj/Welcome.strings + + hash2 + + 3l4+0NbmewoK9l0/qdkIGPcqqrLIRM5eOrwPHGkUEy0= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Signup.strings + + hash2 + + VfV2uL8OKA5ZiR3yiHFT65ZEHaCbkn35Yo+ur18Bqxw= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/UI.strings + + hash2 + + 69DUk8Zeh5SReiVA+Wk9iHozzU98pp8V8uFeG+EA+A0= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/nl.lproj/Welcome.strings + + hash2 + + LHqIVFxiS7xOGRDl+Mc94nzpdWHZpV7V+YNrcO3F6rw= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Signup.strings + + hash2 + + me1r0CSvQxGrjhri1zbZY30vF6XWxdoV5q/XNHlGVhs= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/UI.strings + + hash2 + + frs+aVxqmI1A7qNQ3lTqmaN+e68SScT1D6TutOPSHFs= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pl.lproj/Welcome.strings + + hash2 + + xQJW7uzg6y9kJf1gLZnCM9oO+0wQ84AayU+o+TV5Y2I= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Signup.strings + + hash2 + + MnV7VMLXWFm/KNE5a8UHkxR04f0OznpqoK1+9hyw8zY= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/UI.strings + + hash2 + + DxvjdPIJCkbOywZjS5+ayQkGKWHlrGcquTxizAdezyg= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/pt-BR.lproj/Welcome.strings + + hash2 + + LDC5bZkG2h8AgTQLoL1yMj6JJA/ir2Qs9YoX0A27QLc= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Signup.strings + + hash2 + + WWOM/zJIvlgQASAWOk/VrhJ76xkmJSNIM383qyAebmY= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/UI.strings + + hash2 + + oSkpUWDyzNoWL+/tE+JqlzA0l5XGRGrg0sa5Gvpc4eA= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/ru.lproj/Welcome.strings + + hash2 + + NeG7RvpFs7aBDoclE4CeSnfGf9AS7tGvjGr/m1zT3eY= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Signup.strings + + hash2 + + buuAYnSRdzIW7wnFAfyIoc2xNnPeH6VmMpaTl1UnDcI= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/UI.strings + + hash2 + + 86j7ej1K8vjK2Wc+4VvI8COo0F5VNrFgab6jFb52UQM= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/th.lproj/Welcome.strings + + hash2 + + CWB5kJ7tdPh65LpMEk7ON91tZXYPjCLHG3+KYt/Wor8= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Signup.strings + + hash2 + + J7rTcADNQWVMdE7ToyJl5ztWFP7nS0LpgiIcVb4D/H8= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/UI.strings + + hash2 + + mn9KO/anRw5JkawqXZT06MvC8pSCiTjPxNb+c3RrZ1I= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/tr.lproj/Welcome.strings + + hash2 + + 3U8T+edoinqQskEd4Y8vg0sVEFsjDRp4YCrhcTIq0Nw= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Signup.strings + + hash2 + + 92+yGo0u+BgXiVmoYH9vE1wxCXffUp20Eb5V8JkLJDU= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/UI.strings + + hash2 + + iDsYoUTxx8POedODQmaipEBJukmHm0klpri/JSYxzCg= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hans.lproj/Welcome.strings + + hash2 + + NtHmRVKzAicr7H8AVAqK8Bni236Z2cMnLjdcG/U7T6M= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Signup.strings + + hash2 + + ajON8rkioyflp0u9oIDFniyq4zryBG0tC/51c7OOzbY= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/UI.strings + + hash2 + + IvX18xiU0gageVb9uJLXqnoj5htrqNqSWI1LCqnTWY0= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIALibrary_PIALibrary.bundle/zh-Hant.lproj/Welcome.strings + + hash2 + + E7PBBBbQdDJESlMtJW1vcQ17At7XbJBTHK0Mbm0eyU0= + + optional + + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/Info.plist + + hash2 + + mwC94dBByVRThcNBnzQ+IGHCLsHQKv9SdkUi4cOLyI4= + + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA-RSA-4096.pem + + hash2 + + Mumx0UM+qXYU8qFMbjWOP1fAVwzJ9rLugSaZumlsZqs= + + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/PIA.der + + hash2 + + H9JWWEVuqzBB+6d8zTmKuBJO3MG4svwdVf32sbv8nXA= + + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeDirectory + + hash2 + + 0YGO8yzUacVLcwaChXyFEDV700SjEoA3y4jHNuxE/nQ= + + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements + + hash2 + + mHkgkE6rZQ51eIwFSqCwUk5qgL/HGqMt+NI3phdD+YY= + + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeRequirements-1 + + hash2 + + tlUOZy9wXXkJrqlFG78GXGAwhg6PtVrzl/M9S9NNm64= + + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeResources + + hash2 + + JoxbI6Yk1SD3A2j4qcD82qxRn61PU0HoJwlTobmuafE= + + + PlugIns/PIA VPN WG Tunnel.appex/PIAWireguard_PIAWireguard.bundle/_CodeSignature/CodeSignature + + hash2 + + 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= + + + PlugIns/PIA VPN WG Tunnel.appex/_CodeSignature/CodeResources + + hash2 + + vY5yXk8+eRMYzWx567TwNLLxsoZzei+XLnVUZv0YbLk= + + + PlugIns/PIAWidgetExtension.appex/Assets.car + + hash2 + + VQNnVCtvOsDVJq1++unWMcNu4WBXNcTuaFwQPbbU1n4= + + + PlugIns/PIAWidgetExtension.appex/Base.lproj/PIAWidget.intentdefinition + + hash2 + + 3kTE3lnrdUUlB5l1V5RREqCTVZNj9Txej0o15P1yvZ0= + + optional + + + PlugIns/PIAWidgetExtension.appex/Info.plist + + hash2 + + PJFtwIftArXrDKEgo1kis9M/reFejctMpnIUN4Auhfc= + + + PlugIns/PIAWidgetExtension.appex/PIAWidgetExtension + + hash2 + + 739+fpdzMNG3RWMsxyvN0HcenM2JVbPuCFpLkixwgfw= + + + PlugIns/PIAWidgetExtension.appex/_CodeSignature/CodeResources + + hash2 + + anOjNjk29QQFP+2dItJlhcxnqKmH/a37MYYwZjUEbMI= + + + PlugIns/PIAWidgetExtension.appex/ar.lproj/Localizable.strings + + hash2 + + IkNNXKfp6fE3oi995oVW7WS2woZ1V9mCTjT63KoD9Ek= + + optional + + + PlugIns/PIAWidgetExtension.appex/da.lproj/Localizable.strings + + hash2 + + hktvifgzwYUEObgL+klKwiciZXViqYoni4mEvyH/eDM= + + optional + + + PlugIns/PIAWidgetExtension.appex/de.lproj/Localizable.strings + + hash2 + + eZeauJl1WUEhbBCXDPq2g72GSa4n2ti5+Pxu6lguAHM= + + optional + + + PlugIns/PIAWidgetExtension.appex/en.lproj/Localizable.strings + + hash2 + + fIKEDxEDw26xFvpU5X4CzlGLlP1HJe8GFPiZmM9lmFI= + + optional + + + PlugIns/PIAWidgetExtension.appex/es-MX.lproj/Localizable.strings + + hash2 + + YO/BsBVDZg45VDh/n8em6b1jsIYaOrn8GOq/m5FS55U= + + optional + + + PlugIns/PIAWidgetExtension.appex/fr.lproj/Localizable.strings + + hash2 + + lLmdgPx54cHu/haDrAHx1HPguOP+V194C5zkRchPa4U= + + optional + + + PlugIns/PIAWidgetExtension.appex/it.lproj/Localizable.strings + + hash2 + + i8JZceIPBoBOnxYZPIMHIjJFfomuK99fOu1BWI8qYN8= + + optional + + + PlugIns/PIAWidgetExtension.appex/ja.lproj/Localizable.strings + + hash2 + + q1vazqX4WtbkwrkcAXc3G1cZ9NQ7YqR527Y7LmvcFDE= + + optional + + + PlugIns/PIAWidgetExtension.appex/ko.lproj/Localizable.strings + + hash2 + + Fe5/oYfvjXJchN67Cszo0WFdq6ZKToUQ2MkR5E+pIOw= + + optional + + + PlugIns/PIAWidgetExtension.appex/nb.lproj/Localizable.strings + + hash2 + + +dvIfnHZPLTlDdlCXi1Wyq8OrjFIodLTXRMymQDDdzs= + + optional + + + PlugIns/PIAWidgetExtension.appex/nl.lproj/Localizable.strings + + hash2 + + QBgW2thYGHi8Edrc3QnU/DsqQKMD8x60oH3ZtANVl50= + + optional + + + PlugIns/PIAWidgetExtension.appex/pl.lproj/Localizable.strings + + hash2 + + VgmVDXw7qaceniPAafqE1JWUB2v43XlSajhyklliGcU= + + optional + + + PlugIns/PIAWidgetExtension.appex/pt-BR.lproj/Localizable.strings + + hash2 + + fgG0D/JPPGaD+yPyuPvOR7oxENubkXLPpxTkxIOVkkU= + + optional + + + PlugIns/PIAWidgetExtension.appex/ru.lproj/Localizable.strings + + hash2 + + 4N/PF7IV08Kniait/Y3VwKIWRr9fagf3ieIVPSfi2Hk= + + optional + + + PlugIns/PIAWidgetExtension.appex/th.lproj/Localizable.strings + + hash2 + + XlRWvXzghm9szK5CED5h9yPdxF6uN2/66uugdDNg7i8= + + optional + + + PlugIns/PIAWidgetExtension.appex/tr.lproj/Localizable.strings + + hash2 + + FVRguhv5tetKyZaue31PT6622CPyibxwLQG3ElD9dio= + + optional + + + PlugIns/PIAWidgetExtension.appex/zh-Hans.lproj/Localizable.strings + + hash2 + + FJgmrZ6Fx0JYezPV3t2BnB2JrCqrFL2KNB/cLzsBgCA= + + optional + + + PlugIns/PIAWidgetExtension.appex/zh-Hant.lproj/Localizable.strings + + hash2 + + C1tzFGWrx6ug/O2kor4GCyz/IhltGaWhQDoD4r5fJqw= + + optional + + + QuickConnectTile.nib + + hash2 + + 2i4e+X3lxzbXfTPNghCuIiIB2qRzUOxw2Y6Hh9gwTXo= + + + QuickConnectTileCollectionViewCell.nib/objects-12.3+.nib + + hash2 + + nKQOnd0IMYQ8Ux4v9HSJ7040FXcyeWR7+NHLZKc7mJ8= + + + QuickConnectTileCollectionViewCell.nib/runtime.nib + + hash2 + + 2apDRfA3T9rMJ4NzMH6JlV8xRW+30Hi9LbhX29fMx5A= + + + QuickSettingsTile.nib + + hash2 + + ehJPm2mii/B2EIBNrxcYqL9WwG5Kp6qQUqmA56tB5bQ= + + + QuickSettingsTileCollectionViewCell.nib/objects-12.3+.nib + + hash2 + + jmGgiiihIFDusIDn89NFUOWCvagchAzSmYzHHjsCh8k= + + + QuickSettingsTileCollectionViewCell.nib/runtime.nib + + hash2 + + 1YjRgBawSzVBcp/7p4WRuaJPq15lxL1y0BJRS1KUQtE= + + + RegionTile.nib + + hash2 + + 4jDi7+9o6juxOx4BfVy26qVPXjQV6UmE7xRU3Tpksuw= + + + RegionTileCollectionViewCell.nib/objects-12.3+.nib + + hash2 + + vnHr2j2yDolQ1dCFCvS5SqdnXvFtYUs3fsxjLYfhBEA= + + + RegionTileCollectionViewCell.nib/runtime.nib + + hash2 + + yM5ym5SHTSdEuA7DrTDwLcgwdy3yOGzC60KbC+ia1vs= + + + Regions.json + + hash2 + + MWUsh0F7tUZlmKa36MgLVhYM2afc8oZzPIOYQVo2ui0= + + + Roboto-Light.ttf + + hash2 + + ptND1CW8ONuQFS+gYFixxzkeypJk8zTvZcHOF1CFxvY= + + + Roboto-Medium.ttf + + hash2 + + 8gXMURgh6lYHihBVV/zqYlMSlATUEcmX4YZvvQBqu2g= + + + Roboto-Regular.ttf + + hash2 + + eehRQEZX2sIQaz0irSVtR4JKmldlRY7bcskQKkWBbZU= + + + Roboto-Thin.ttf + + hash2 + + PZH3qmnLf3BkA1iVxWasXLmyCEWC01Gvcme7Tg+6YPU= + + + SubscriptionTile.nib + + hash2 + + dkmUWReQYA3qVte+WXwlz8g1Nd1lmbOUhVHjwsxK6Fw= + + + SubscriptionTileCollectionViewCell.nib/objects-12.3+.nib + + hash2 + + 7OLkPBOBVOE6RRVA/EwJRt+r4T56cWbLKwgafxgzpoA= + + + SubscriptionTileCollectionViewCell.nib/runtime.nib + + hash2 + + IdBYYlug9f8LzH2r3FS76qOLh2gVeFaAiwZfNmDcMbw= + + + UsageTile.nib + + hash2 + + mg9wg23FuKFA0j9ANEhQ0bGui/vBAqr2N1Xujli2hw0= + + + UsageTileCollectionViewCell.nib/objects-12.3+.nib + + hash2 + + pDPMyUQ5k271UqTULDwkWse/I7+cDGMUV47dVU8W8Vc= + + + UsageTileCollectionViewCell.nib/runtime.nib + + hash2 + + odleg/IV0WkbMhmsCuldiAFCkpPhWECqCyBqExAbEkc= + + + ar.lproj/InfoPlist.strings + + hash2 + + iulah/dhXowF5jVEsWrIwDu/Js7gtcQ0PB54lQL7QJE= + + optional + + + ar.lproj/Localizable.strings + + hash2 + + IkNNXKfp6fE3oi995oVW7WS2woZ1V9mCTjT63KoD9Ek= + + optional + + + custom.servers + + hash2 + + AbpHGcgLb+kRsJGnwFEktk7uzpZOCcBY74+YBdrKVGs= + + + da.lproj/InfoPlist.strings + + hash2 + + Sdg7zmEVmxpr3wHLIYfQN3N6JJbtPs9mefAMD1udOqM= + + optional + + + da.lproj/Localizable.strings + + hash2 + + hktvifgzwYUEObgL+klKwiciZXViqYoni4mEvyH/eDM= + + optional + + + de.lproj/InfoPlist.strings + + hash2 + + JsUrWAEaoxRrK8wE2tTYaq00usyxWBFxb677aKoaxgw= + + optional + + + de.lproj/Localizable.strings + + hash2 + + eZeauJl1WUEhbBCXDPq2g72GSa4n2ti5+Pxu6lguAHM= + + optional + + + en.lproj/InfoPlist.strings + + hash2 + + YVLNKD7FOx0Ny7SEhYEsSU4SjsybNo0MFRVetj2rrto= + + optional + + + en.lproj/Localizable.strings + + hash2 + + fIKEDxEDw26xFvpU5X4CzlGLlP1HJe8GFPiZmM9lmFI= + + optional + + + en.lproj/Main.storyboardc/8GT-4Z-Eox-view-QZg-xz-wXy.nib + + hash2 + + C/43kyfSC6D/IKfykO48malAHfOfERhf6bWSxpb0G0s= + + optional + + + en.lproj/Main.storyboardc/BNo-Ag-Vl2-view-8tS-UG-dKk.nib + + hash2 + + S901bAgqOLAC/wsUr+sesyD9bdzsYKs0dzyEMl4WdN0= + + optional + + + en.lproj/Main.storyboardc/BP1-69-boB-view-LKz-D5-KlE.nib + + hash2 + + 2EZLRUdJDe7zBCuTWI89hvBYnknbq+s3Eyh8elwEC8c= + + optional + + + en.lproj/Main.storyboardc/BcC-bW-Cr7-view-b9l-eX-dk8.nib + + hash2 + + S901bAgqOLAC/wsUr+sesyD9bdzsYKs0dzyEMl4WdN0= + + optional + + + en.lproj/Main.storyboardc/CEm-fv-KfP-view-R8e-Ar-VG0.nib + + hash2 + + dtrNOL9sD+VbDk1erSNE/d+7fWjlyNCjdxstaScUI3s= + + optional + + + en.lproj/Main.storyboardc/ConfirmVPNPlanViewController.nib + + hash2 + + Z2phSndTWJMRGlD3KMDppNcsbw7ga3wdE81gS0EbRd8= + + optional + + + en.lproj/Main.storyboardc/Info.plist + + hash2 + + I7iCtEFqylg9DU2KEKyib2tNUk5GnK5EWulFiFTvtP8= + + optional + + + en.lproj/Main.storyboardc/Jcq-Qm-xQ1-view-3ye-eb-yzU.nib + + hash2 + + Uxi6lpHsrI9HzZQGxyfTpXO4jWL4okExbWiIpIpJ59I= + + optional + + + en.lproj/Main.storyboardc/LrP-0B-Ym4-view-R3h-W3-NNr.nib + + hash2 + + gG5JNjLX+ZfSo9Ienisa+dFwyyxNv3lXHhJD8PMOO4A= + + optional + + + en.lproj/Main.storyboardc/Ltp-Dt-4e7-view-kgw-5Z-a7U.nib + + hash2 + + paBH3U9houmUlWH1CYg9bDzb3lICkDRu5lr7+ssg92I= + + optional + + + en.lproj/Main.storyboardc/MU8-v2-7Zn-view-Rsa-kn-TH2.nib + + hash2 + + /FLe8pTuMp+hEcYBllIjP05bf4MQS84aEt6lmWEKfjU= + + optional + + + en.lproj/Main.storyboardc/PIACardsViewController.nib + + hash2 + + ECAwGPks/VKwozOLLOELE9OwwO6sahh6cEkIJKzUxic= + + optional + + + en.lproj/Main.storyboardc/PW2-xO-eP5-view-dN1-YI-Ruq.nib + + hash2 + + pYH9NiLqQyxSNx1Jx/Y+Y92TDRpCKk2gZLGTGX93xsk= + + optional + + + en.lproj/Main.storyboardc/SAw-ll-7Hp-view-H9q-Rn-fdF.nib + + hash2 + + nIw7OYPeSuYuifS6FRkWgJRFpITwJBiG8LB3l8Yt1yg= + + optional + + + en.lproj/Main.storyboardc/SideMenuNavigationController.nib + + hash2 + + 598h2pPr2Ch/D20z5GONGJWg4b+xHASWPR7Vq1JN4fM= + + optional + + + en.lproj/Main.storyboardc/UINavigationController-GHB-bv-bDF.nib + + hash2 + + zCdkRGbvD0eAtPZTkdfbVdQb/b0Qa4XmwEC52XEyle4= + + optional + + + en.lproj/Main.storyboardc/UINavigationController-boO-X9-UIe.nib + + hash2 + + Y6f/bizmqLl/MQB12XntDwsTdTgtC/vsLqG05AdY4qk= + + optional + + + en.lproj/Main.storyboardc/UIViewController-BNo-Ag-Vl2.nib + + hash2 + + cazrdggJ7/09fYgDrt1Zp2ghwjq+oLqljFFtmagRjPc= + + optional + + + en.lproj/Main.storyboardc/UIViewController-BP1-69-boB.nib + + hash2 + + oIHBcKuvnPFsbDbEkYWH3aa3aCa2HBItn2yylx/ms1I= + + optional + + + en.lproj/Main.storyboardc/UIViewController-BcC-bW-Cr7.nib + + hash2 + + M2Z/HnK58TeELaGvcLBgHCVUriOxkw9OYbDb3kFdwsI= + + optional + + + en.lproj/Main.storyboardc/UIViewController-LrP-0B-Ym4.nib + + hash2 + + n8mWVFgiuf63i1+UCWaHoOlX2wamULzr6Dj7zITRO3I= + + optional + + + en.lproj/Main.storyboardc/UIViewController-Ltp-Dt-4e7.nib + + hash2 + + cHBL2bDt8DbKBpYl28FhNq/CJOPI5x2IGNs6EznY1MU= + + optional + + + en.lproj/Main.storyboardc/UIViewController-MU8-v2-7Zn.nib + + hash2 + + cwCGsfca/AjpfXhn333NFqafgTXj4yY84izW4PWVQtk= + + optional + + + en.lproj/Main.storyboardc/UIViewController-PW2-xO-eP5.nib + + hash2 + + GIcWkrZA2kp//YRZ/hi9HtndyWhIxhnvWIKj2YTMHjs= + + optional + + + en.lproj/Main.storyboardc/UIViewController-SAw-ll-7Hp.nib + + hash2 + + LCoMEq4xgmw0jFsmsZZNNBiGHCsgCrwmLIGYiXuDse4= + + optional + + + en.lproj/Main.storyboardc/UIViewController-W4F-zm-KqY.nib + + hash2 + + JzgWj++5XtEkT2Zr2Nzh4d3fAbWEwmLemjt/7wx7+PU= + + optional + + + en.lproj/Main.storyboardc/UIViewController-ckY-cv-bTr.nib + + hash2 + + aB32+9XscR4ta1GbP5njCaw494kS69VPmBBwudsAXa8= + + optional + + + en.lproj/Main.storyboardc/UIViewController-dAM-Z5-oAd.nib + + hash2 + + jEvrNcokKr0oGnbp8Q/9QheT9cEQP04l5tWUJJJE5iE= + + optional + + + en.lproj/Main.storyboardc/UIViewController-dQc-D3-32b.nib + + hash2 + + MLsjaWxUwv2BU6hcasXB6n/vJzJnJaQdAEp8844L7tQ= + + optional + + + en.lproj/Main.storyboardc/UIViewController-eBS-0e-zkL.nib + + hash2 + + VJrppUh1vCnmSDyRxa0iLeJftp3rz9xcc1jLy9f+eok= + + optional + + + en.lproj/Main.storyboardc/UIViewController-jy7-91-daJ.nib + + hash2 + + 10VzF3S0gXFEOvGGx2suOwWedPYPDhBUDAmGBKJ36TY= + + optional + + + en.lproj/Main.storyboardc/UIViewController-rTx-sq-4Hq.nib + + hash2 + + m8St706J3XWUH2uv77AYhzSqnjKfM8IdgiuzWIqrv0M= + + optional + + + en.lproj/Main.storyboardc/UIViewController-tRS-0y-Z0e.nib + + hash2 + + +qe8grpAzixJ+Tjmb377P9M7Bsa/H4k4EZ7EfebPcig= + + optional + + + en.lproj/Main.storyboardc/UIViewController-uom-Te-eRI.nib + + hash2 + + d9eF4+AhNnZRN5SmdEbBvFZourSnrRmndwtLXIYjeLo= + + optional + + + en.lproj/Main.storyboardc/UIViewController-ytC-cJ-8NL.nib + + hash2 + + aj68o1nD7epbJfyY6Z8H0iXmB2RFAaMyqcL+DutYcgQ= + + optional + + + en.lproj/Main.storyboardc/VPNPermissionViewController.nib + + hash2 + + E5//nPHx0bUsnic8qRmjeR8WDNXKZk9rtdLnpnBLuuc= + + optional + + + en.lproj/Main.storyboardc/W4F-zm-KqY-view-xbM-if-7h8.nib + + hash2 + + k5aNWnEj/mvr4DWMFcDjhFz9eZ7d1l7TeUu+6LK5Rqs= + + optional + + + en.lproj/Main.storyboardc/ckY-cv-bTr-view-VtZ-Wr-diD.nib + + hash2 + + D1aK8nu6BnHDPgAxE2D+U7ZtG0lFhL5NyKQ63a41jf0= + + optional + + + en.lproj/Main.storyboardc/dAM-Z5-oAd-view-t5R-BN-3Wx.nib + + hash2 + + yGslwAgPo2U8agfc8UCyQEFXMOetd9xA5aeG3YbrIbY= + + optional + + + en.lproj/Main.storyboardc/dQc-D3-32b-view-if1-76-vY3.nib + + hash2 + + S901bAgqOLAC/wsUr+sesyD9bdzsYKs0dzyEMl4WdN0= + + optional + + + en.lproj/Main.storyboardc/eBS-0e-zkL-view-Ax3-s6-smO.nib + + hash2 + + S901bAgqOLAC/wsUr+sesyD9bdzsYKs0dzyEMl4WdN0= + + optional + + + en.lproj/Main.storyboardc/fek-Xn-fRR-view-PEc-bc-lz4.nib + + hash2 + + 9ilptt/0U3zKjA7Ncuc4/PX+uTv8vo32e5vGB647gNQ= + + optional + + + en.lproj/Main.storyboardc/fzy-5R-TDW-view-Enl-Vx-oZs.nib + + hash2 + + ZixItVCqWs04SxlnwI/4/9txiEyWqLWT5S0GQQRDApY= + + optional + + + en.lproj/Main.storyboardc/g6e-47-VJ0-view-Oy9-GF-TW7.nib + + hash2 + + DYORloG1ZqFpw6nI6XFPCU06oLsa1ikJZKOYYxvGsmU= + + optional + + + en.lproj/Main.storyboardc/jy7-91-daJ-view-P5B-eT-Ius.nib + + hash2 + + +8BOF5M5upyxvdDM29EXhPT5gAb1CMPHcO/eBPPiCJg= + + optional + + + en.lproj/Main.storyboardc/rTx-sq-4Hq-view-jUh-De-KQu.nib + + hash2 + + +xYNT4zwCZ/e7rFUJX32n38Ul0xrTZPb4Dp5TtACn5w= + + optional + + + en.lproj/Main.storyboardc/tRS-0y-Z0e-view-5si-tE-vZl.nib + + hash2 + + S901bAgqOLAC/wsUr+sesyD9bdzsYKs0dzyEMl4WdN0= + + optional + + + en.lproj/Main.storyboardc/uom-Te-eRI-view-ibw-l8-EcR.nib + + hash2 + + S901bAgqOLAC/wsUr+sesyD9bdzsYKs0dzyEMl4WdN0= + + optional + + + en.lproj/Main.storyboardc/ytC-cJ-8NL-view-QFu-xx-xle.nib + + hash2 + + lkwB/vF9GQYiOtTCa1ceXQBhDyJKXhDtdSxYJzSToF0= + + optional + + + es-MX.lproj/InfoPlist.strings + + hash2 + + k5RkmwAt7EVI3g3VFVkJPitKbQ6S7tAv0yDTJc5Ujhk= + + optional + + + es-MX.lproj/Localizable.strings + + hash2 + + YO/BsBVDZg45VDh/n8em6b1jsIYaOrn8GOq/m5FS55U= + + optional + + + fr.lproj/InfoPlist.strings + + hash2 + + adiOA9AHB+ssftGtGqWikkgr+zpx4sdPzWAF8/wC2cM= + + optional + + + fr.lproj/Localizable.strings + + hash2 + + lLmdgPx54cHu/haDrAHx1HPguOP+V194C5zkRchPa4U= + + optional + + + it.lproj/InfoPlist.strings + + hash2 + + jTdB9whu4CGbg9Q5536fSKBLZ1eLzmpwQFzU36KEKc0= + + optional + + + it.lproj/Localizable.strings + + hash2 + + i8JZceIPBoBOnxYZPIMHIjJFfomuK99fOu1BWI8qYN8= + + optional + + + ja.lproj/InfoPlist.strings + + hash2 + + 6Dj+aPMmYakSSEMajbKgx5pt5Un64a5r3e9QYUiyXQk= + + optional + + + ja.lproj/Localizable.strings + + hash2 + + q1vazqX4WtbkwrkcAXc3G1cZ9NQ7YqR527Y7LmvcFDE= + + optional + + + ko.lproj/InfoPlist.strings + + hash2 + + H160Ik8oXWgZ7akXLimmeyELtuRAH/nA6OvdK1V6jM0= + + optional + + + ko.lproj/Localizable.strings + + hash2 + + Fe5/oYfvjXJchN67Cszo0WFdq6ZKToUQ2MkR5E+pIOw= + + optional + + + nb.lproj/InfoPlist.strings + + hash2 + + PITdq0TNXiy6QFr7VLxqyrOORNkwUI84Ld7KCzSvBes= + + optional + + + nb.lproj/Localizable.strings + + hash2 + + +dvIfnHZPLTlDdlCXi1Wyq8OrjFIodLTXRMymQDDdzs= + + optional + + + nl.lproj/InfoPlist.strings + + hash2 + + jPKPSntPY8k7EQjidvzO5VglTniuyq0tX4/M2UMIsng= + + optional + + + nl.lproj/Localizable.strings + + hash2 + + QBgW2thYGHi8Edrc3QnU/DsqQKMD8x60oH3ZtANVl50= + + optional + + + pia-spinner.json + + hash2 + + yziZbGZtq5dGdoQVQKgVVzpA1RsXwkaPIVJgmYR9Y+M= + + + pl.lproj/InfoPlist.strings + + hash2 + + DXVTaixUzajDh6AQ0FEL03xXoT0gLzFPFyxc093iEdU= + + optional + + + pl.lproj/Localizable.strings + + hash2 + + VgmVDXw7qaceniPAafqE1JWUB2v43XlSajhyklliGcU= + + optional + + + pt-BR.lproj/InfoPlist.strings + + hash2 + + BKhyplMoYzldeqduXzlmXt4PIvGpWNCIxka0r3DNJ5w= + + optional + + + pt-BR.lproj/Localizable.strings + + hash2 + + fgG0D/JPPGaD+yPyuPvOR7oxENubkXLPpxTkxIOVkkU= + + optional + + + ru.lproj/InfoPlist.strings + + hash2 + + MdvGXhOsMKUjsNQO+hcLRRQEM8iTeAChCUSEtvU6DSk= + + optional + + + ru.lproj/Localizable.strings + + hash2 + + 4N/PF7IV08Kniait/Y3VwKIWRr9fagf3ieIVPSfi2Hk= + + optional + + + staging.endpoint + + hash2 + + AbpHGcgLb+kRsJGnwFEktk7uzpZOCcBY74+YBdrKVGs= + + + th.lproj/InfoPlist.strings + + hash2 + + Xav8XuHQy2XDnnHJICvC4FgTIWq0Z8Gvx6wnJskMp4M= + + optional + + + th.lproj/Localizable.strings + + hash2 + + XlRWvXzghm9szK5CED5h9yPdxF6uN2/66uugdDNg7i8= + + optional + + + tr.lproj/InfoPlist.strings + + hash2 + + kQu8hrAqItYEoGjBS56Fb3sSOErojL43Oc5l6IqiSXA= + + optional + + + tr.lproj/Localizable.strings + + hash2 + + FVRguhv5tetKyZaue31PT6622CPyibxwLQG3ElD9dio= + + optional + + + zh-Hans.lproj/InfoPlist.strings + + hash2 + + 5OEZsLRMOn11CM4h7kPFtC5WCSOR+krLODyc/W9F1TM= + + optional + + + zh-Hans.lproj/Localizable.strings + + hash2 + + FJgmrZ6Fx0JYezPV3t2BnB2JrCqrFL2KNB/cLzsBgCA= + + optional + + + zh-Hant.lproj/InfoPlist.strings + + hash2 + + fGF9m3tc567sK7n7ZalhjX8GNI6twWM1xeIAI2xSnDA= + + optional + + + zh-Hant.lproj/Localizable.strings + + hash2 + + C1tzFGWrx6ug/O2kor4GCyz/IhltGaWhQDoD4r5fJqw= + + optional + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/PIA VPN dev.app/ar.lproj/InfoPlist.strings b/PIA VPN dev.app/ar.lproj/InfoPlist.strings new file mode 100644 index 000000000..7739c6a64 Binary files /dev/null and b/PIA VPN dev.app/ar.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/ar.lproj/Localizable.strings b/PIA VPN dev.app/ar.lproj/Localizable.strings new file mode 100644 index 000000000..72f251cba Binary files /dev/null and b/PIA VPN dev.app/ar.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/custom.servers b/PIA VPN dev.app/custom.servers new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/PIA VPN dev.app/custom.servers @@ -0,0 +1 @@ + diff --git a/PIA VPN dev.app/da.lproj/InfoPlist.strings b/PIA VPN dev.app/da.lproj/InfoPlist.strings new file mode 100644 index 000000000..87a79dbc0 Binary files /dev/null and b/PIA VPN dev.app/da.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/da.lproj/Localizable.strings b/PIA VPN dev.app/da.lproj/Localizable.strings new file mode 100644 index 000000000..da84165f3 Binary files /dev/null and b/PIA VPN dev.app/da.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/de.lproj/InfoPlist.strings b/PIA VPN dev.app/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..1669aa744 Binary files /dev/null and b/PIA VPN dev.app/de.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/de.lproj/Localizable.strings b/PIA VPN dev.app/de.lproj/Localizable.strings new file mode 100644 index 000000000..e96d881b7 Binary files /dev/null and b/PIA VPN dev.app/de.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/en.lproj/InfoPlist.strings b/PIA VPN dev.app/en.lproj/InfoPlist.strings new file mode 100644 index 000000000..863310e5c Binary files /dev/null and b/PIA VPN dev.app/en.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/en.lproj/Localizable.strings b/PIA VPN dev.app/en.lproj/Localizable.strings new file mode 100644 index 000000000..b8cb811ae Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/8GT-4Z-Eox-view-QZg-xz-wXy.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/8GT-4Z-Eox-view-QZg-xz-wXy.nib new file mode 100644 index 000000000..695bf7733 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/8GT-4Z-Eox-view-QZg-xz-wXy.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/BNo-Ag-Vl2-view-8tS-UG-dKk.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/BNo-Ag-Vl2-view-8tS-UG-dKk.nib new file mode 100644 index 000000000..28e3ee48f Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/BNo-Ag-Vl2-view-8tS-UG-dKk.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/BP1-69-boB-view-LKz-D5-KlE.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/BP1-69-boB-view-LKz-D5-KlE.nib new file mode 100644 index 000000000..416ba9452 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/BP1-69-boB-view-LKz-D5-KlE.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/BcC-bW-Cr7-view-b9l-eX-dk8.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/BcC-bW-Cr7-view-b9l-eX-dk8.nib new file mode 100644 index 000000000..28e3ee48f Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/BcC-bW-Cr7-view-b9l-eX-dk8.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/CEm-fv-KfP-view-R8e-Ar-VG0.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/CEm-fv-KfP-view-R8e-Ar-VG0.nib new file mode 100644 index 000000000..e1f3a81d9 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/CEm-fv-KfP-view-R8e-Ar-VG0.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/ConfirmVPNPlanViewController.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/ConfirmVPNPlanViewController.nib new file mode 100644 index 000000000..05965ee6b Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/ConfirmVPNPlanViewController.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/Info.plist b/PIA VPN dev.app/en.lproj/Main.storyboardc/Info.plist new file mode 100644 index 000000000..06be43274 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/Info.plist differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/Jcq-Qm-xQ1-view-3ye-eb-yzU.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/Jcq-Qm-xQ1-view-3ye-eb-yzU.nib new file mode 100644 index 000000000..ad206a13e Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/Jcq-Qm-xQ1-view-3ye-eb-yzU.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/LrP-0B-Ym4-view-R3h-W3-NNr.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/LrP-0B-Ym4-view-R3h-W3-NNr.nib new file mode 100644 index 000000000..87cbf52e8 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/LrP-0B-Ym4-view-R3h-W3-NNr.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/Ltp-Dt-4e7-view-kgw-5Z-a7U.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/Ltp-Dt-4e7-view-kgw-5Z-a7U.nib new file mode 100644 index 000000000..f7e85e3d3 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/Ltp-Dt-4e7-view-kgw-5Z-a7U.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/MU8-v2-7Zn-view-Rsa-kn-TH2.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/MU8-v2-7Zn-view-Rsa-kn-TH2.nib new file mode 100644 index 000000000..65a1ec7ab Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/MU8-v2-7Zn-view-Rsa-kn-TH2.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/PIACardsViewController.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/PIACardsViewController.nib new file mode 100644 index 000000000..e35c669d1 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/PIACardsViewController.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/PW2-xO-eP5-view-dN1-YI-Ruq.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/PW2-xO-eP5-view-dN1-YI-Ruq.nib new file mode 100644 index 000000000..90e79a1ff Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/PW2-xO-eP5-view-dN1-YI-Ruq.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/SAw-ll-7Hp-view-H9q-Rn-fdF.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/SAw-ll-7Hp-view-H9q-Rn-fdF.nib new file mode 100644 index 000000000..60d5b3c06 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/SAw-ll-7Hp-view-H9q-Rn-fdF.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/SideMenuNavigationController.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/SideMenuNavigationController.nib new file mode 100644 index 000000000..912631a54 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/SideMenuNavigationController.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UINavigationController-GHB-bv-bDF.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UINavigationController-GHB-bv-bDF.nib new file mode 100644 index 000000000..5e4eceeec Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UINavigationController-GHB-bv-bDF.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UINavigationController-boO-X9-UIe.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UINavigationController-boO-X9-UIe.nib new file mode 100644 index 000000000..130e87fe6 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UINavigationController-boO-X9-UIe.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-BNo-Ag-Vl2.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-BNo-Ag-Vl2.nib new file mode 100644 index 000000000..671472e0a Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-BNo-Ag-Vl2.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-BP1-69-boB.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-BP1-69-boB.nib new file mode 100644 index 000000000..afa4bf5e0 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-BP1-69-boB.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-BcC-bW-Cr7.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-BcC-bW-Cr7.nib new file mode 100644 index 000000000..6d10b1d77 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-BcC-bW-Cr7.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-LrP-0B-Ym4.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-LrP-0B-Ym4.nib new file mode 100644 index 000000000..03f7587a5 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-LrP-0B-Ym4.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-Ltp-Dt-4e7.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-Ltp-Dt-4e7.nib new file mode 100644 index 000000000..f0affb1a1 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-Ltp-Dt-4e7.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-MU8-v2-7Zn.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-MU8-v2-7Zn.nib new file mode 100644 index 000000000..4d2ce5d36 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-MU8-v2-7Zn.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-PW2-xO-eP5.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-PW2-xO-eP5.nib new file mode 100644 index 000000000..161e2147e Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-PW2-xO-eP5.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-SAw-ll-7Hp.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-SAw-ll-7Hp.nib new file mode 100644 index 000000000..01dd71be3 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-SAw-ll-7Hp.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-W4F-zm-KqY.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-W4F-zm-KqY.nib new file mode 100644 index 000000000..2078f9fd2 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-W4F-zm-KqY.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-ckY-cv-bTr.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-ckY-cv-bTr.nib new file mode 100644 index 000000000..a13056de3 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-ckY-cv-bTr.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-dAM-Z5-oAd.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-dAM-Z5-oAd.nib new file mode 100644 index 000000000..be5804049 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-dAM-Z5-oAd.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-dQc-D3-32b.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-dQc-D3-32b.nib new file mode 100644 index 000000000..d5df53875 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-dQc-D3-32b.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-eBS-0e-zkL.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-eBS-0e-zkL.nib new file mode 100644 index 000000000..83495ad13 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-eBS-0e-zkL.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-jy7-91-daJ.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-jy7-91-daJ.nib new file mode 100644 index 000000000..5b8141d83 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-jy7-91-daJ.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-rTx-sq-4Hq.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-rTx-sq-4Hq.nib new file mode 100644 index 000000000..b4260b1aa Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-rTx-sq-4Hq.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-tRS-0y-Z0e.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-tRS-0y-Z0e.nib new file mode 100644 index 000000000..ba74d1cb1 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-tRS-0y-Z0e.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-uom-Te-eRI.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-uom-Te-eRI.nib new file mode 100644 index 000000000..35536feb5 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-uom-Te-eRI.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-ytC-cJ-8NL.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-ytC-cJ-8NL.nib new file mode 100644 index 000000000..1238c5b43 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/UIViewController-ytC-cJ-8NL.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/VPNPermissionViewController.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/VPNPermissionViewController.nib new file mode 100644 index 000000000..9a9801c27 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/VPNPermissionViewController.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/W4F-zm-KqY-view-xbM-if-7h8.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/W4F-zm-KqY-view-xbM-if-7h8.nib new file mode 100644 index 000000000..f9ef8d424 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/W4F-zm-KqY-view-xbM-if-7h8.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/ckY-cv-bTr-view-VtZ-Wr-diD.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/ckY-cv-bTr-view-VtZ-Wr-diD.nib new file mode 100644 index 000000000..f2ad9fed4 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/ckY-cv-bTr-view-VtZ-Wr-diD.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/dAM-Z5-oAd-view-t5R-BN-3Wx.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/dAM-Z5-oAd-view-t5R-BN-3Wx.nib new file mode 100644 index 000000000..276a9508c Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/dAM-Z5-oAd-view-t5R-BN-3Wx.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/dQc-D3-32b-view-if1-76-vY3.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/dQc-D3-32b-view-if1-76-vY3.nib new file mode 100644 index 000000000..28e3ee48f Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/dQc-D3-32b-view-if1-76-vY3.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/eBS-0e-zkL-view-Ax3-s6-smO.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/eBS-0e-zkL-view-Ax3-s6-smO.nib new file mode 100644 index 000000000..28e3ee48f Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/eBS-0e-zkL-view-Ax3-s6-smO.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/fek-Xn-fRR-view-PEc-bc-lz4.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/fek-Xn-fRR-view-PEc-bc-lz4.nib new file mode 100644 index 000000000..05cdad15e Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/fek-Xn-fRR-view-PEc-bc-lz4.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/fzy-5R-TDW-view-Enl-Vx-oZs.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/fzy-5R-TDW-view-Enl-Vx-oZs.nib new file mode 100644 index 000000000..7d11bbb6a Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/fzy-5R-TDW-view-Enl-Vx-oZs.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/g6e-47-VJ0-view-Oy9-GF-TW7.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/g6e-47-VJ0-view-Oy9-GF-TW7.nib new file mode 100644 index 000000000..9807726c8 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/g6e-47-VJ0-view-Oy9-GF-TW7.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/jy7-91-daJ-view-P5B-eT-Ius.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/jy7-91-daJ-view-P5B-eT-Ius.nib new file mode 100644 index 000000000..bb0ab8daa Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/jy7-91-daJ-view-P5B-eT-Ius.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/rTx-sq-4Hq-view-jUh-De-KQu.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/rTx-sq-4Hq-view-jUh-De-KQu.nib new file mode 100644 index 000000000..0d429bbe8 Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/rTx-sq-4Hq-view-jUh-De-KQu.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/tRS-0y-Z0e-view-5si-tE-vZl.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/tRS-0y-Z0e-view-5si-tE-vZl.nib new file mode 100644 index 000000000..28e3ee48f Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/tRS-0y-Z0e-view-5si-tE-vZl.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/uom-Te-eRI-view-ibw-l8-EcR.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/uom-Te-eRI-view-ibw-l8-EcR.nib new file mode 100644 index 000000000..28e3ee48f Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/uom-Te-eRI-view-ibw-l8-EcR.nib differ diff --git a/PIA VPN dev.app/en.lproj/Main.storyboardc/ytC-cJ-8NL-view-QFu-xx-xle.nib b/PIA VPN dev.app/en.lproj/Main.storyboardc/ytC-cJ-8NL-view-QFu-xx-xle.nib new file mode 100644 index 000000000..97d97956a Binary files /dev/null and b/PIA VPN dev.app/en.lproj/Main.storyboardc/ytC-cJ-8NL-view-QFu-xx-xle.nib differ diff --git a/PIA VPN dev.app/es-MX.lproj/InfoPlist.strings b/PIA VPN dev.app/es-MX.lproj/InfoPlist.strings new file mode 100644 index 000000000..06a080916 Binary files /dev/null and b/PIA VPN dev.app/es-MX.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/es-MX.lproj/Localizable.strings b/PIA VPN dev.app/es-MX.lproj/Localizable.strings new file mode 100644 index 000000000..2ba8b2a4b Binary files /dev/null and b/PIA VPN dev.app/es-MX.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/fr.lproj/InfoPlist.strings b/PIA VPN dev.app/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..5c3818ff6 Binary files /dev/null and b/PIA VPN dev.app/fr.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/fr.lproj/Localizable.strings b/PIA VPN dev.app/fr.lproj/Localizable.strings new file mode 100644 index 000000000..be5e0d3d8 Binary files /dev/null and b/PIA VPN dev.app/fr.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/it.lproj/InfoPlist.strings b/PIA VPN dev.app/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..d2faf0771 Binary files /dev/null and b/PIA VPN dev.app/it.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/it.lproj/Localizable.strings b/PIA VPN dev.app/it.lproj/Localizable.strings new file mode 100644 index 000000000..2c200bad3 Binary files /dev/null and b/PIA VPN dev.app/it.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/ja.lproj/InfoPlist.strings b/PIA VPN dev.app/ja.lproj/InfoPlist.strings new file mode 100644 index 000000000..a498e2344 Binary files /dev/null and b/PIA VPN dev.app/ja.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/ja.lproj/Localizable.strings b/PIA VPN dev.app/ja.lproj/Localizable.strings new file mode 100644 index 000000000..54e000008 Binary files /dev/null and b/PIA VPN dev.app/ja.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/ko.lproj/InfoPlist.strings b/PIA VPN dev.app/ko.lproj/InfoPlist.strings new file mode 100644 index 000000000..4ea192897 Binary files /dev/null and b/PIA VPN dev.app/ko.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/ko.lproj/Localizable.strings b/PIA VPN dev.app/ko.lproj/Localizable.strings new file mode 100644 index 000000000..6bc04227c Binary files /dev/null and b/PIA VPN dev.app/ko.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/nb.lproj/InfoPlist.strings b/PIA VPN dev.app/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..86e956c94 Binary files /dev/null and b/PIA VPN dev.app/nb.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/nb.lproj/Localizable.strings b/PIA VPN dev.app/nb.lproj/Localizable.strings new file mode 100644 index 000000000..6f0dec437 Binary files /dev/null and b/PIA VPN dev.app/nb.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/nl.lproj/InfoPlist.strings b/PIA VPN dev.app/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..37b626851 Binary files /dev/null and b/PIA VPN dev.app/nl.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/nl.lproj/Localizable.strings b/PIA VPN dev.app/nl.lproj/Localizable.strings new file mode 100644 index 000000000..87038baa2 Binary files /dev/null and b/PIA VPN dev.app/nl.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/pia-spinner.json b/PIA VPN dev.app/pia-spinner.json new file mode 100644 index 000000000..35b478c1e --- /dev/null +++ b/PIA VPN dev.app/pia-spinner.json @@ -0,0 +1 @@ +{"v":"5.1.17","fr":29.9700012207031,"ip":0,"op":90.0000036657751,"w":160,"h":160,"nm":"spinner","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"green","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[1080]},{"t":90.0000036657751}],"ix":10},"p":{"a":0,"k":[80,80,0],"ix":2},"a":{"a":0,"k":[80,80,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-25.344],[0,0],[20.629,12.196],[0,0]],"o":[[0,0],[0,-23.936],[0,0],[21.841,12.912]],"v":[[18.722,31.01],[14.722,31.01],[-18.722,-27.567],[-16.687,-31.01]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":3,"k":{"a":0,"k":[0,0.298,0.714,0.286,0.5,0.298,0.714,0.286,1,0.298,0.714,0.286,0,1,0.5,0.9,0.999,0.8],"ix":9}},"s":{"a":0,"k":[17.593,28.038],"ix":5},"e":{"a":0,"k":[17.708,-27.53],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[133.331,49.101],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[12.669,-11.968],[0,0],[-18.463,0],[-11.042,-6.528],[0,0],[12.18,0]],"o":[[0,0],[13.415,-12.673],[12.895,0],[0,0],[-10.427,-6.164],[-17.437,0]],"v":[[-40.265,11.28],[-43.012,8.372],[6.422,-11.28],[43.012,-1.301],[40.977,2.142],[6.422,-7.28]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":3,"k":{"a":0,"k":[0,0.298,0.714,0.286,0.5,0.298,0.714,0.286,1,0.298,0.714,0.286,0,0.8,0.5,0.7,1,0.6],"ix":9}},"s":{"a":0,"k":[36.252,1.852],"ix":5},"e":{"a":0,"k":[-36.911,1.539],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[73.578,19.28],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,16.235],[-14.552,13.747],[0,0],[0,-18.9],[-9.422,-12.049]],"o":[[-9.979,-12.76],[0,-20.011],[0,0],[-13.744,12.983],[0,15.333],[0,0]],"v":[[2.596,48.335],[-12.656,4.015],[9.91,-48.335],[12.656,-45.426],[-8.656,4.015],[5.747,45.87]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":3,"k":{"a":0,"k":[0,0.298,0.714,0.286,0.5,0.298,0.714,0.286,1,0.298,0.714,0.286,0,0.4,0.5,0.5,1,0.6],"ix":9}},"s":{"a":0,"k":[1.303,42.93],"ix":5},"e":{"a":0,"k":[0.576,-44.195],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[20.657,75.986],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[17.645,0],[13.758,17.591],[0,0],[-21.066,0],[-12.446,11.055],[0,0]],"o":[[-22.306,0],[0,0],[12.994,16.616],[16.664,0],[0,0],[-13.178,11.706]],"v":[[4.475,15.073],[-52.272,-12.607],[-49.121,-15.072],[4.475,11.073],[49.616,-6.07],[52.272,-3.079]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":3,"k":{"a":0,"k":[0,0.298,0.714,0.286,0.5,0.298,0.714,0.286,1,0.298,0.714,0.286,0,0.4,0.5,0.3,1,0.2],"ix":9}},"s":{"a":0,"k":[-48.376,-12.58],"ix":5},"e":{"a":0,"k":[51.078,-4.37],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[75.525,136.927],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.066,-11.606],[0,0],[-2.053,16.294],[0,0]],"o":[[0,0],[12.342,-10.963],[0,0],[-2.175,17.256]],"v":[[-10.49,22.629],[-13.146,19.639],[9.176,-22.629],[13.145,-22.129]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":3,"k":{"a":0,"k":[0,0.298,0.714,0.286,0.5,0.298,0.714,0.286,1,0.298,0.714,0.286,0,0,0.5,0.1,1,0.2],"ix":9}},"s":{"a":0,"k":[11.308,-22.716],"ix":5},"e":{"a":0,"k":[-11.557,20.516],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[138.286,111.219],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90.0000036657751,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/PIA VPN dev.app/pl.lproj/InfoPlist.strings b/PIA VPN dev.app/pl.lproj/InfoPlist.strings new file mode 100644 index 000000000..cdeea4111 Binary files /dev/null and b/PIA VPN dev.app/pl.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/pl.lproj/Localizable.strings b/PIA VPN dev.app/pl.lproj/Localizable.strings new file mode 100644 index 000000000..6079451a9 Binary files /dev/null and b/PIA VPN dev.app/pl.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/pt-BR.lproj/InfoPlist.strings b/PIA VPN dev.app/pt-BR.lproj/InfoPlist.strings new file mode 100644 index 000000000..528635c85 Binary files /dev/null and b/PIA VPN dev.app/pt-BR.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/pt-BR.lproj/Localizable.strings b/PIA VPN dev.app/pt-BR.lproj/Localizable.strings new file mode 100644 index 000000000..9f5f6f8b8 Binary files /dev/null and b/PIA VPN dev.app/pt-BR.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/ru.lproj/InfoPlist.strings b/PIA VPN dev.app/ru.lproj/InfoPlist.strings new file mode 100644 index 000000000..3bfabfa13 Binary files /dev/null and b/PIA VPN dev.app/ru.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/ru.lproj/Localizable.strings b/PIA VPN dev.app/ru.lproj/Localizable.strings new file mode 100644 index 000000000..1a694cc7e Binary files /dev/null and b/PIA VPN dev.app/ru.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/staging.endpoint b/PIA VPN dev.app/staging.endpoint new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/PIA VPN dev.app/staging.endpoint @@ -0,0 +1 @@ + diff --git a/PIA VPN dev.app/th.lproj/InfoPlist.strings b/PIA VPN dev.app/th.lproj/InfoPlist.strings new file mode 100644 index 000000000..28fb89d19 Binary files /dev/null and b/PIA VPN dev.app/th.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/th.lproj/Localizable.strings b/PIA VPN dev.app/th.lproj/Localizable.strings new file mode 100644 index 000000000..cc9175d02 Binary files /dev/null and b/PIA VPN dev.app/th.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/tr.lproj/InfoPlist.strings b/PIA VPN dev.app/tr.lproj/InfoPlist.strings new file mode 100644 index 000000000..959584201 Binary files /dev/null and b/PIA VPN dev.app/tr.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/tr.lproj/Localizable.strings b/PIA VPN dev.app/tr.lproj/Localizable.strings new file mode 100644 index 000000000..a9d781293 Binary files /dev/null and b/PIA VPN dev.app/tr.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/zh-Hans.lproj/InfoPlist.strings b/PIA VPN dev.app/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 000000000..71aa71f95 Binary files /dev/null and b/PIA VPN dev.app/zh-Hans.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/zh-Hans.lproj/Localizable.strings b/PIA VPN dev.app/zh-Hans.lproj/Localizable.strings new file mode 100644 index 000000000..bc047f587 Binary files /dev/null and b/PIA VPN dev.app/zh-Hans.lproj/Localizable.strings differ diff --git a/PIA VPN dev.app/zh-Hant.lproj/InfoPlist.strings b/PIA VPN dev.app/zh-Hant.lproj/InfoPlist.strings new file mode 100644 index 000000000..c6908fe00 Binary files /dev/null and b/PIA VPN dev.app/zh-Hant.lproj/InfoPlist.strings differ diff --git a/PIA VPN dev.app/zh-Hant.lproj/Localizable.strings b/PIA VPN dev.app/zh-Hant.lproj/Localizable.strings new file mode 100644 index 000000000..e9ab32d0d Binary files /dev/null and b/PIA VPN dev.app/zh-Hant.lproj/Localizable.strings differ diff --git a/PIA VPN.xcodeproj/project.pbxproj b/PIA VPN.xcodeproj/project.pbxproj index 1e43708e9..d1ccc06fe 100644 --- a/PIA VPN.xcodeproj/project.pbxproj +++ b/PIA VPN.xcodeproj/project.pbxproj @@ -3,17 +3,14 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ - 078FA875634A84BD6728DF93 /* Pods_PIA_VPN_WG_Tunnel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28DFD7434ECA3047EB4A2C75 /* Pods_PIA_VPN_WG_Tunnel.framework */; }; 0E0715E7201CBB7100D6F666 /* Flags-dev.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0E0715E5201CBB7100D6F666 /* Flags-dev.plist */; }; 0E0786DE1EFA7EAE00F77466 /* Components.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0E0786DD1EFA7EAE00F77466 /* Components.plist */; }; 0E1F318620176A5F00FC1000 /* Theme+DarkPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1F318520176A5F00FC1000 /* Theme+DarkPalette.swift */; }; 0E1F318720176A6300FC1000 /* Theme+DarkPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1F318520176A5F00FC1000 /* Theme+DarkPalette.swift */; }; - 0E2215C920084CD700F5FB4D /* SwiftGen+Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E2215C820084CD700F5FB4D /* SwiftGen+Strings.swift */; }; - 0E2215CA2008BA9100F5FB4D /* SwiftGen+Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E2215C820084CD700F5FB4D /* SwiftGen+Strings.swift */; }; 0E2215CC2008BF8300F5FB4D /* SwiftGen+Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E2215CB2008BF8300F5FB4D /* SwiftGen+Assets.swift */; }; 0E2215CD2008C01D00F5FB4D /* SwiftGen+Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E2215CB2008BF8300F5FB4D /* SwiftGen+Assets.swift */; }; 0E392DA61FE3283C0002160D /* TransientState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E392DA51FE3283C0002160D /* TransientState.swift */; }; @@ -128,7 +125,6 @@ 0EFDC1ED1FE4B9DC007C0B9B /* AppConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFDC1EB1FE4B9DC007C0B9B /* AppConstants.swift */; }; 0EFDC1EF1FE4B9E6007C0B9B /* AppConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFDC1EE1FE4B9E6007C0B9B /* AppConfiguration.swift */; }; 0EFDC1F01FE4B9E6007C0B9B /* AppConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFDC1EE1FE4B9E6007C0B9B /* AppConfiguration.swift */; }; - 12CE273914ED9E7533E3A51E /* Pods_PIA_VPN_dev.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CA493DF6602BFDE96E0E77F /* Pods_PIA_VPN_dev.framework */; }; 2909869018566430002D9687 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2909868F18566430002D9687 /* Security.framework */; }; 291C6380183EBC210039EC03 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 291C637F183EBC210039EC03 /* Foundation.framework */; }; 291C6382183EBC210039EC03 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 291C6381183EBC210039EC03 /* CoreGraphics.framework */; }; @@ -147,8 +143,54 @@ 3545E98226AADB2B00B812CC /* ServerSelectingTileCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3545E98126AADB2B00B812CC /* ServerSelectingTileCell.swift */; }; 3545E98326AADC7C00B812CC /* ServerSelectingTileCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3545E98126AADB2B00B812CC /* ServerSelectingTileCell.swift */; }; 3545E98426AADC7E00B812CC /* ServerSelectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3545E97F26AAD60C00B812CC /* ServerSelectionDelegate.swift */; }; - 3732E0F0C64DA8513903087D /* Pods_PIA_VPN_Tunnel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02823EF3398B7E2C32FA7544 /* Pods_PIA_VPN_Tunnel.framework */; }; - 73E0B0544DF023785B11C4B9 /* Pods_PIA_VPN.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E23999135612F39173E9C1E /* Pods_PIA_VPN.framework */; }; + 35950B312ADD2996006F3CD9 /* Quick in Frameworks */ = {isa = PBXBuildFile; productRef = 35950B302ADD2996006F3CD9 /* Quick */; }; + 35950B342ADD2EE5006F3CD9 /* Nimble in Frameworks */ = {isa = PBXBuildFile; productRef = 35950B332ADD2EE5006F3CD9 /* Nimble */; }; + 35EDD6282ADE5D31007B9ACB /* BaseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35EDD6272ADE5D31007B9ACB /* BaseTest.swift */; }; + 35EDD62A2ADE5F08007B9ACB /* SignInTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35EDD6292ADE5F08007B9ACB /* SignInTests.swift */; }; + 35EDD6332ADE7281007B9ACB /* OnboardingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35EDD6322ADE7281007B9ACB /* OnboardingTests.swift */; }; + 35EDD6352ADE7424007B9ACB /* VPNPermissionScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35EDD6342ADE7424007B9ACB /* VPNPermissionScreen.swift */; }; + 35EDD6372ADE761A007B9ACB /* HomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35EDD6362ADE761A007B9ACB /* HomeScreen.swift */; }; + 35EDD63B2AE62D15007B9ACB /* ElementHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35EDD63A2AE62D15007B9ACB /* ElementHelper.swift */; }; + 35EDD63E2AE76A3B007B9ACB /* WaitHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35EDD63D2AE76A3B007B9ACB /* WaitHelper.swift */; }; + 35EDD6422AE7A83D007B9ACB /* WelcomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35EDD6412AE7A83D007B9ACB /* WelcomeScreen.swift */; }; + 35EDD6442AE7B480007B9ACB /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35EDD6432AE7B480007B9ACB /* Common.swift */; }; + 35EDD65A2B035B51007B9ACB /* SideMenuScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35EDD6592B035B51007B9ACB /* SideMenuScreen.swift */; }; + 35EDD65C2B047839007B9ACB /* QuickSettingsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35EDD65B2B047839007B9ACB /* QuickSettingsTests.swift */; }; + 35EDD65E2B048C68007B9ACB /* QuickSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35EDD65D2B048C68007B9ACB /* QuickSettingsScreen.swift */; }; + 6924831A2AB045A5002A0407 /* PIAWidgetAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 692483192AB045A5002A0407 /* PIAWidgetAttributes.swift */; }; + 6924831B2AB045A5002A0407 /* PIAWidgetAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 692483192AB045A5002A0407 /* PIAWidgetAttributes.swift */; }; + 6924831C2AB045A5002A0407 /* PIAWidgetAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 692483192AB045A5002A0407 /* PIAWidgetAttributes.swift */; }; + 6924831E2AB04FFD002A0407 /* PIAWidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6924831D2AB04FFD002A0407 /* PIAWidgetBundle.swift */; }; + 692483202AB05F18002A0407 /* PIAConnectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6924831F2AB05F18002A0407 /* PIAConnectionView.swift */; }; + 692483222AB05F37002A0407 /* PIACircleIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 692483212AB05F37002A0407 /* PIACircleIcon.swift */; }; + 692483262AB05F85002A0407 /* PIAConnectionActivityWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 692483252AB05F85002A0407 /* PIAConnectionActivityWidget.swift */; }; + 695BF81D2AC30EFB00D1139C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0E7EC043209326E30029811E /* Localizable.strings */; }; + 695BF81F2AC410E000D1139C /* SwiftGen+Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E2215C820084CD700F5FB4D /* SwiftGen+Strings.swift */; }; + 697C59AC2AFD0771008B6212 /* PIALibrary in Frameworks */ = {isa = PBXBuildFile; productRef = 697C59AB2AFD0770008B6212 /* PIALibrary */; }; + 697C59AE2AFD0786008B6212 /* PIALibrary in Frameworks */ = {isa = PBXBuildFile; productRef = 697C59AD2AFD0786008B6212 /* PIALibrary */; }; + 697C59B02AFD0791008B6212 /* PIALibrary in Frameworks */ = {isa = PBXBuildFile; productRef = 697C59AF2AFD0791008B6212 /* PIALibrary */; }; + 697C59B22AFD079B008B6212 /* PIALibrary in Frameworks */ = {isa = PBXBuildFile; productRef = 697C59B12AFD079B008B6212 /* PIALibrary */; }; + 698F4F2B2AB8A2080010B2B0 /* PIAWidgetExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 8269A6D5251CB5E0000B4DBF /* PIAWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 698F4F2D2AB978BF0010B2B0 /* PIACircleImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 698F4F2C2AB978BF0010B2B0 /* PIACircleImageView.swift */; }; + 698F4F2E2AB97BAD0010B2B0 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 291C6397183EBC210039EC03 /* Images.xcassets */; }; + 698F4F302ABA1DA10010B2B0 /* PIAConnectionLiveActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 698F4F2F2ABA1DA10010B2B0 /* PIAConnectionLiveActivityManager.swift */; }; + 698F4F312ABA1DA10010B2B0 /* PIAConnectionLiveActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 698F4F2F2ABA1DA10010B2B0 /* PIAConnectionLiveActivityManager.swift */; }; + 698F4F322ABA1DA10010B2B0 /* PIAConnectionLiveActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 698F4F2F2ABA1DA10010B2B0 /* PIAConnectionLiveActivityManager.swift */; }; + 699F23B22AFBA66000EBC5E6 /* SettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 699F23AC2AFBA66000EBC5E6 /* SettingsScreen.swift */; }; + 699F23B32AFBA66000EBC5E6 /* HelpSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 699F23AD2AFBA66000EBC5E6 /* HelpSettingsScreen.swift */; }; + 699F23B42AFBA66000EBC5E6 /* AutomationSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 699F23AE2AFBA66000EBC5E6 /* AutomationSettingsScreen.swift */; }; + 699F23B52AFBA66000EBC5E6 /* ProtocolsSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 699F23AF2AFBA66000EBC5E6 /* ProtocolsSettingsScreen.swift */; }; + 699F23B62AFBA66000EBC5E6 /* GeneralSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 699F23B02AFBA66000EBC5E6 /* GeneralSettingsScreen.swift */; }; + 699F23B72AFBA66000EBC5E6 /* PrivacySettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 699F23B12AFBA66000EBC5E6 /* PrivacySettingsScreen.swift */; }; + 699F23B92AFBAC0B00EBC5E6 /* UpdateSettingsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 699F23B82AFBAC0B00EBC5E6 /* UpdateSettingsTests.swift */; }; + 69B70AB52ACBF51C0072A09D /* LoginScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69B70AB42ACBF51C0072A09D /* LoginScreen.swift */; }; + 69B70ABC2ACBF8300072A09D /* CredentialsUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EC2972D27D8B8580061C56A /* CredentialsUtil.swift */; }; + 69B70ABE2ACC2CFE0072A09D /* AccessibilityId.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69B70ABD2ACC2CFE0072A09D /* AccessibilityId.swift */; }; + 69B70ABF2ACC2CFE0072A09D /* AccessibilityId.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69B70ABD2ACC2CFE0072A09D /* AccessibilityId.swift */; }; + 69B70AC02ACC2CFE0072A09D /* AccessibilityId.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69B70ABD2ACC2CFE0072A09D /* AccessibilityId.swift */; }; + 69C587FD2AD00C6300B95EF9 /* PIAExampleWithAuthenticatedAppTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69C587FC2AD00C6300B95EF9 /* PIAExampleWithAuthenticatedAppTest.swift */; }; + 7ECBB8DD27B6C4F500C0C774 /* UserSurveyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECBB8DC27B6C4F500C0C774 /* UserSurveyManager.swift */; }; + 7ECBB8DE27BA5FCE00C0C774 /* UserSurveyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECBB8DC27B6C4F500C0C774 /* UserSurveyManager.swift */; }; 821674F12678A1BE0028E4FD /* SettingsDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821674F02678A1BE0028E4FD /* SettingsDelegate.swift */; }; 821674F22678A1BE0028E4FD /* SettingsDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821674F02678A1BE0028E4FD /* SettingsDelegate.swift */; }; 82183D7B2500FD460033023F /* String+Substrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82183D7A2500FD460033023F /* String+Substrings.swift */; }; @@ -162,7 +204,7 @@ 82183D9C25014FDC0033023F /* PIAHeaderCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 82183D9525014FDC0033023F /* PIAHeaderCollectionViewCell.xib */; }; 82183D9D25014FDC0033023F /* PIAHeaderCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 82183D9525014FDC0033023F /* PIAHeaderCollectionViewCell.xib */; }; 8221922B24CECFE700C24F1C /* NMTTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8221922A24CECFE700C24F1C /* NMTTests.swift */; }; - 822F97B4251DD53100644EF2 /* WidgetUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 822F97B3251DD53100644EF2 /* WidgetUtils.swift */; }; + 822F97B4251DD53100644EF2 /* WidgetUserDefaultsDatasource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 822F97B3251DD53100644EF2 /* WidgetUserDefaultsDatasource.swift */; }; 824C530824C046CB003DB740 /* ConnectionTile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824C530724C046CA003DB740 /* ConnectionTile.swift */; }; 824C530924C046CB003DB740 /* ConnectionTile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824C530724C046CA003DB740 /* ConnectionTile.swift */; }; 824C531524C04796003DB740 /* ConnectionTileCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824C531324C04796003DB740 /* ConnectionTileCollectionViewCell.swift */; }; @@ -176,7 +218,7 @@ 8269A6DA251CB5E0000B4DBF /* PIAWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8269A6D9251CB5E0000B4DBF /* PIAWidget.swift */; }; 8269A6DD251CB5E3000B4DBF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8269A6DC251CB5E3000B4DBF /* Assets.xcassets */; }; 8269A6E3251CB5E3000B4DBF /* PIAWidgetExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 8269A6D5251CB5E0000B4DBF /* PIAWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 8269A6FE251CBB36000B4DBF /* WidgetContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8269A6FD251CBB36000B4DBF /* WidgetContent.swift */; }; + 8269A6FE251CBB36000B4DBF /* WidgetInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8269A6FD251CBB36000B4DBF /* WidgetInformation.swift */; }; 826BE8EE253861BE002339F3 /* DedicatedRegionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 826BE8ED253861BE002339F3 /* DedicatedRegionCell.swift */; }; 826BE8EF253861BE002339F3 /* DedicatedRegionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 826BE8ED253861BE002339F3 /* DedicatedRegionCell.swift */; }; 8272C62726540B2100D846A8 /* ProtocolSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8272C62626540B2100D846A8 /* ProtocolSettingsViewController.swift */; }; @@ -247,7 +289,6 @@ 82CAB87B255AEA3500BB08EF /* MessagesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAB879255AEA3500BB08EF /* MessagesManager.swift */; }; 82CAB8B0255B050000BB08EF /* MessagesCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAB8AF255B050000BB08EF /* MessagesCommands.swift */; }; 82CAB8B1255B050000BB08EF /* MessagesCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAB8AF255B050000BB08EF /* MessagesCommands.swift */; }; - 82CAB8DA255BEC7000BB08EF /* PIACommandTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAB8D9255BEC7000BB08EF /* PIACommandTests.swift */; }; 82CAB8E8255C0CB000BB08EF /* MessagesTile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAB8E7255C0CB000BB08EF /* MessagesTile.swift */; }; 82CAB8E9255C0CB000BB08EF /* MessagesTile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAB8E7255C0CB000BB08EF /* MessagesTile.swift */; }; 82CAB8F2255C0CD100BB08EF /* MessagesTileCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CAB8F0255C0CD100BB08EF /* MessagesTileCollectionViewCell.swift */; }; @@ -258,7 +299,28 @@ 82CAB8FE255C115100BB08EF /* MessagesTile.xib in Resources */ = {isa = PBXBuildFile; fileRef = 82CAB8FC255C115100BB08EF /* MessagesTile.xib */; }; 82F41376264E8AC20098FF4B /* SettingOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F41375264E8AC20098FF4B /* SettingOptions.swift */; }; 82F41377264E8AC20098FF4B /* SettingOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F41375264E8AC20098FF4B /* SettingOptions.swift */; }; - 929703E310E04502651A34E9 /* Pods_PIA_VPNTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F453DF1F58B8C2676041EDF /* Pods_PIA_VPNTests.framework */; }; + AA36CDBB28A6622A00180A33 /* TweetNacl in Frameworks */ = {isa = PBXBuildFile; productRef = AA36CDBA28A6622A00180A33 /* TweetNacl */; }; + AA36CDC428A6711300180A33 /* Popover in Frameworks */ = {isa = PBXBuildFile; productRef = AA36CDC328A6711300180A33 /* Popover */; }; + AA36CDC928A6733500180A33 /* DZNEmptyDataSet in Frameworks */ = {isa = PBXBuildFile; productRef = AA36CDC828A6733500180A33 /* DZNEmptyDataSet */; }; + AA36CDCC28A673C900180A33 /* GradientProgressBar in Frameworks */ = {isa = PBXBuildFile; productRef = AA36CDCB28A673C900180A33 /* GradientProgressBar */; }; + AA36CDCF28A6746500180A33 /* SideMenu in Frameworks */ = {isa = PBXBuildFile; productRef = AA36CDCE28A6746500180A33 /* SideMenu */; }; + AA36CDDB28A6860F00180A33 /* TweetNacl in Frameworks */ = {isa = PBXBuildFile; productRef = AA36CDDA28A6860F00180A33 /* TweetNacl */; }; + AA36CDDE28A6878000180A33 /* AlamofireImage in Frameworks */ = {isa = PBXBuildFile; productRef = AA36CDDD28A6878000180A33 /* AlamofireImage */; }; + AA52C59F28E5ECD400D025AF /* PIAWidgetVpnDetaislRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA52C59E28E5ECD400D025AF /* PIAWidgetVpnDetaislRow.swift */; }; + AABF826D28AD185E00CDAC64 /* TweetNacl in Frameworks */ = {isa = PBXBuildFile; productRef = AABF826C28AD185E00CDAC64 /* TweetNacl */; }; + AABF826F28AD187800CDAC64 /* Popover in Frameworks */ = {isa = PBXBuildFile; productRef = AABF826E28AD187800CDAC64 /* Popover */; }; + AABF827128AD188700CDAC64 /* AlamofireImage in Frameworks */ = {isa = PBXBuildFile; productRef = AABF827028AD188700CDAC64 /* AlamofireImage */; }; + AABF827328AE2FF500CDAC64 /* GradientProgressBar in Frameworks */ = {isa = PBXBuildFile; productRef = AABF827228AE2FF500CDAC64 /* GradientProgressBar */; }; + AABF827528AE2FFE00CDAC64 /* SideMenu in Frameworks */ = {isa = PBXBuildFile; productRef = AABF827428AE2FFE00CDAC64 /* SideMenu */; }; + AABF827628AE302300CDAC64 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD606AB921C7A17900E0781D /* NetworkExtension.framework */; }; + AABF827828AE333200CDAC64 /* DZNEmptyDataSet in Frameworks */ = {isa = PBXBuildFile; productRef = AABF827728AE333200CDAC64 /* DZNEmptyDataSet */; }; + AAE8789C28E4679500557F26 /* WidgetPersistenceDatasource.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE8789B28E4679500557F26 /* WidgetPersistenceDatasource.swift */; }; + AAE8789F28E4696300557F26 /* PIAWidgetProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE8789E28E4696300557F26 /* PIAWidgetProvider.swift */; }; + AAE878A128E46C1600557F26 /* PIAWidgetPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE878A028E46C1600557F26 /* PIAWidgetPreview.swift */; }; + AAE878A328E46D2B00557F26 /* PIAWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE878A228E46D2B00557F26 /* PIAWidgetView.swift */; }; + AAE878A528E4723B00557F26 /* PIACircleVpnButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE878A428E4723B00557F26 /* PIACircleVpnButton.swift */; }; + AAE878A728E473A400557F26 /* PIAWidgetVpnDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE878A628E473A400557F26 /* PIAWidgetVpnDetailsView.swift */; }; + AAE878A928E4765F00557F26 /* PIAIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE878A828E4765F00557F26 /* PIAIconView.swift */; }; DD052AC32419003300AD3A24 /* ProtocolTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD052AC22419003300AD3A24 /* ProtocolTableViewCell.swift */; }; DD052AC42419020E00AD3A24 /* ProtocolTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD052AC22419003300AD3A24 /* ProtocolTableViewCell.swift */; }; DD07AACC242CBFF2000EE1A3 /* AddEmailToAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD07AACB242CBFF2000EE1A3 /* AddEmailToAccountViewController.swift */; }; @@ -310,7 +372,6 @@ DD51F8C52372E4C8009FEED3 /* PemUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD51F8C32372E4C8009FEED3 /* PemUtil.swift */; }; DD522D22237D74380072F555 /* BooleanUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD522D21237D74380072F555 /* BooleanUtil.swift */; }; DD522D23237D74380072F555 /* BooleanUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD522D21237D74380072F555 /* BooleanUtil.swift */; }; - DD58F4B821AD579A00D043F7 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = DD58F4B721AD579A00D043F7 /* GoogleService-Info.plist */; }; DD58F4BF21B12CFE00D043F7 /* PIAConnectionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD58F4BE21B12CFE00D043F7 /* PIAConnectionButton.swift */; }; DD58F4C021B12CFE00D043F7 /* PIAConnectionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD58F4BE21B12CFE00D043F7 /* PIAConnectionButton.swift */; }; DD606ABA21C7A17900E0781D /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD606AB921C7A17900E0781D /* NetworkExtension.framework */; }; @@ -386,6 +447,96 @@ DDFCFA9521E892130081F235 /* RegionTile.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFCFA9321E892130081F235 /* RegionTile.swift */; }; DDFCFA9721E8921F0081F235 /* RegionTile.xib in Resources */ = {isa = PBXBuildFile; fileRef = DDFCFA9621E8921F0081F235 /* RegionTile.xib */; }; DDFCFA9821E8921F0081F235 /* RegionTile.xib in Resources */ = {isa = PBXBuildFile; fileRef = DDFCFA9621E8921F0081F235 /* RegionTile.xib */; }; + E501CBB32AE97EBA00515006 /* Signup.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E501CBB22AE97EBA00515006 /* Signup.storyboard */; }; + E501CBB42AE97EBA00515006 /* Signup.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E501CBB22AE97EBA00515006 /* Signup.storyboard */; }; + E501CBB62AE97EC800515006 /* Welcome.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E501CBB52AE97EC800515006 /* Welcome.storyboard */; }; + E501CBB72AE97EC800515006 /* Welcome.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E501CBB52AE97EC800515006 /* Welcome.storyboard */; }; + E501CBF52AE9806800515006 /* UI.strings in Resources */ = {isa = PBXBuildFile; fileRef = E501CBBA2AE9806800515006 /* UI.strings */; }; + E501CBF62AE9806800515006 /* UI.strings in Resources */ = {isa = PBXBuildFile; fileRef = E501CBBA2AE9806800515006 /* UI.strings */; }; + E501CBF72AE9806800515006 /* Signup.strings in Resources */ = {isa = PBXBuildFile; fileRef = E501CBCE2AE9806800515006 /* Signup.strings */; }; + E501CBF82AE9806800515006 /* Signup.strings in Resources */ = {isa = PBXBuildFile; fileRef = E501CBCE2AE9806800515006 /* Signup.strings */; }; + E501CBF92AE9806800515006 /* Welcome.strings in Resources */ = {isa = PBXBuildFile; fileRef = E501CBD02AE9806800515006 /* Welcome.strings */; }; + E501CBFA2AE9806800515006 /* Welcome.strings in Resources */ = {isa = PBXBuildFile; fileRef = E501CBD02AE9806800515006 /* Welcome.strings */; }; + E501CBFB2AE9806800515006 /* UI.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E501CBDC2AE9806800515006 /* UI.xcassets */; }; + E501CBFC2AE9806800515006 /* UI.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E501CBDC2AE9806800515006 /* UI.xcassets */; }; + E51693C62AFAD3550089FB8F /* UIDevice+WIFI.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51693C52AFAD3550089FB8F /* UIDevice+WIFI.swift */; }; + E51693C92AFAD5130089FB8F /* PIALibrary in Frameworks */ = {isa = PBXBuildFile; productRef = E51693C82AFAD5130089FB8F /* PIALibrary */; }; + E51693CB2AFAD51B0089FB8F /* PIALibrary in Frameworks */ = {isa = PBXBuildFile; productRef = E51693CA2AFAD51B0089FB8F /* PIALibrary */; }; + E51693CD2AFAD5290089FB8F /* PIALibrary in Frameworks */ = {isa = PBXBuildFile; productRef = E51693CC2AFAD5290089FB8F /* PIALibrary */; }; + E51693CF2AFAD52F0089FB8F /* PIALibrary in Frameworks */ = {isa = PBXBuildFile; productRef = E51693CE2AFAD52F0089FB8F /* PIALibrary */; }; + E51693D12AFADCC20089FB8F /* SwiftGen+Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51693D02AFADCC20089FB8F /* SwiftGen+Strings.swift */; }; + E51693D22AFADCC20089FB8F /* SwiftGen+Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51693D02AFADCC20089FB8F /* SwiftGen+Strings.swift */; }; + E51693D32AFAE3670089FB8F /* SwiftGen+Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51693D02AFADCC20089FB8F /* SwiftGen+Strings.swift */; }; + E51693D52AFBDB8A0089FB8F /* NavigationBar+Appearence..swift in Sources */ = {isa = PBXBuildFile; fileRef = E51693D42AFBDB8A0089FB8F /* NavigationBar+Appearence..swift */; }; + E51693D62AFBDB8A0089FB8F /* NavigationBar+Appearence..swift in Sources */ = {isa = PBXBuildFile; fileRef = E51693D42AFBDB8A0089FB8F /* NavigationBar+Appearence..swift */; }; + E51693D82AFBE5680089FB8F /* CAGradientLayer+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51693D72AFBE5680089FB8F /* CAGradientLayer+Image.swift */; }; + E51693D92AFBE5680089FB8F /* CAGradientLayer+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51693D72AFBE5680089FB8F /* CAGradientLayer+Image.swift */; }; + E5217F392AEA7B0E00123442 /* Macros+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F382AEA7B0E00123442 /* Macros+UI.swift */; }; + E5217F3A2AEA7B0E00123442 /* Macros+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F382AEA7B0E00123442 /* Macros+UI.swift */; }; + E5217F3C2AEA886000123442 /* BorderedTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F3B2AEA886000123442 /* BorderedTextField.swift */; }; + E5217F3D2AEA886000123442 /* BorderedTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F3B2AEA886000123442 /* BorderedTextField.swift */; }; + E5217F402AEAC7A900123442 /* Theme+LightPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F3E2AEAC7A900123442 /* Theme+LightPalette.swift */; }; + E5217F412AEAC7A900123442 /* Theme+LightPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F3E2AEAC7A900123442 /* Theme+LightPalette.swift */; }; + E5217F422AEAC7A900123442 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F3F2AEAC7A900123442 /* Theme.swift */; }; + E5217F432AEAC7A900123442 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F3F2AEAC7A900123442 /* Theme.swift */; }; + E5217F452AEACE0200123442 /* NavigationLogoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F442AEACE0200123442 /* NavigationLogoView.swift */; }; + E5217F462AEACE0200123442 /* NavigationLogoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F442AEACE0200123442 /* NavigationLogoView.swift */; }; + E5217F482AEAD28000123442 /* UIViewLoading.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F472AEAD28000123442 /* UIViewLoading.swift */; }; + E5217F492AEAD28000123442 /* UIViewLoading.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F472AEAD28000123442 /* UIViewLoading.swift */; }; + E5217F4B2AEAD29F00123442 /* PurchasePlanCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F4A2AEAD29F00123442 /* PurchasePlanCell.swift */; }; + E5217F4C2AEAD29F00123442 /* PurchasePlanCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F4A2AEAD29F00123442 /* PurchasePlanCell.swift */; }; + E5217F542AEAD54600123442 /* WalkthroughPageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F532AEAD54600123442 /* WalkthroughPageView.swift */; }; + E5217F552AEAD54600123442 /* WalkthroughPageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F532AEAD54600123442 /* WalkthroughPageView.swift */; }; + E5217F5D2AEAE01400123442 /* NotificationCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F5C2AEAE01400123442 /* NotificationCategory.swift */; }; + E5217F5E2AEAE01400123442 /* NotificationCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F5C2AEAE01400123442 /* NotificationCategory.swift */; }; + E5217F662AEAF94C00123442 /* SwiftGen+Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F652AEAF94C00123442 /* SwiftGen+Assets.swift */; }; + E5217F672AEAF94C00123442 /* SwiftGen+Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F652AEAF94C00123442 /* SwiftGen+Assets.swift */; }; + E5217F6F2AEB042800123442 /* ClientError+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F6E2AEB042800123442 /* ClientError+Localization.swift */; }; + E5217F702AEB042800123442 /* ClientError+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F6E2AEB042800123442 /* ClientError+Localization.swift */; }; + E5217F722AEB055D00123442 /* Client+Storyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F712AEB055D00123442 /* Client+Storyboard.swift */; }; + E5217F732AEB055D00123442 /* Client+Storyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5217F712AEB055D00123442 /* Client+Storyboard.swift */; }; + E59E8F942AEA7A29009278F5 /* ActivityButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F932AEA7A29009278F5 /* ActivityButton.swift */; }; + E59E8F952AEA7A29009278F5 /* ActivityButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F932AEA7A29009278F5 /* ActivityButton.swift */; }; + E59E8F972AEA7A5A009278F5 /* AutolayoutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F962AEA7A5A009278F5 /* AutolayoutViewController.swift */; }; + E59E8F982AEA7A5A009278F5 /* AutolayoutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F962AEA7A5A009278F5 /* AutolayoutViewController.swift */; }; + E59E8FA92AEA7A81009278F5 /* SignupInternetUnreachableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F992AEA7A7F009278F5 /* SignupInternetUnreachableViewController.swift */; }; + E59E8FAA2AEA7A81009278F5 /* SignupInternetUnreachableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F992AEA7A7F009278F5 /* SignupInternetUnreachableViewController.swift */; }; + E59E8FAB2AEA7A81009278F5 /* SignupSuccessViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F9A2AEA7A7F009278F5 /* SignupSuccessViewController.swift */; }; + E59E8FAC2AEA7A81009278F5 /* SignupSuccessViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F9A2AEA7A7F009278F5 /* SignupSuccessViewController.swift */; }; + E59E8FAD2AEA7A81009278F5 /* SignupInProgressViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F9B2AEA7A7F009278F5 /* SignupInProgressViewController.swift */; }; + E59E8FAE2AEA7A81009278F5 /* SignupInProgressViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F9B2AEA7A7F009278F5 /* SignupInProgressViewController.swift */; }; + E59E8FAF2AEA7A81009278F5 /* MagicLinkLoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F9C2AEA7A80009278F5 /* MagicLinkLoginViewController.swift */; }; + E59E8FB02AEA7A81009278F5 /* MagicLinkLoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F9C2AEA7A80009278F5 /* MagicLinkLoginViewController.swift */; }; + E59E8FB12AEA7A81009278F5 /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F9D2AEA7A80009278F5 /* LoginViewController.swift */; }; + E59E8FB22AEA7A81009278F5 /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F9D2AEA7A80009278F5 /* LoginViewController.swift */; }; + E59E8FB32AEA7A81009278F5 /* PIAWelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F9E2AEA7A80009278F5 /* PIAWelcomeViewController.swift */; }; + E59E8FB42AEA7A81009278F5 /* PIAWelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F9E2AEA7A80009278F5 /* PIAWelcomeViewController.swift */; }; + E59E8FB52AEA7A81009278F5 /* GetStartedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F9F2AEA7A80009278F5 /* GetStartedViewController.swift */; }; + E59E8FB62AEA7A81009278F5 /* GetStartedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8F9F2AEA7A80009278F5 /* GetStartedViewController.swift */; }; + E59E8FB72AEA7A81009278F5 /* ConfirmVPNPlanViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA02AEA7A80009278F5 /* ConfirmVPNPlanViewController.swift */; }; + E59E8FB82AEA7A81009278F5 /* ConfirmVPNPlanViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA02AEA7A80009278F5 /* ConfirmVPNPlanViewController.swift */; }; + E59E8FB92AEA7A81009278F5 /* RestoreSignupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA12AEA7A80009278F5 /* RestoreSignupViewController.swift */; }; + E59E8FBA2AEA7A81009278F5 /* RestoreSignupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA12AEA7A80009278F5 /* RestoreSignupViewController.swift */; }; + E59E8FBB2AEA7A81009278F5 /* GDPRViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA22AEA7A80009278F5 /* GDPRViewController.swift */; }; + E59E8FBC2AEA7A81009278F5 /* GDPRViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA22AEA7A80009278F5 /* GDPRViewController.swift */; }; + E59E8FBD2AEA7A81009278F5 /* SignupFailureViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA32AEA7A80009278F5 /* SignupFailureViewController.swift */; }; + E59E8FBE2AEA7A81009278F5 /* SignupFailureViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA32AEA7A80009278F5 /* SignupFailureViewController.swift */; }; + E59E8FBF2AEA7A81009278F5 /* WelcomePageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA42AEA7A80009278F5 /* WelcomePageViewController.swift */; }; + E59E8FC02AEA7A81009278F5 /* WelcomePageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA42AEA7A80009278F5 /* WelcomePageViewController.swift */; }; + E59E8FC12AEA7A81009278F5 /* ShareDataInformationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA52AEA7A81009278F5 /* ShareDataInformationViewController.swift */; }; + E59E8FC22AEA7A81009278F5 /* ShareDataInformationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA52AEA7A81009278F5 /* ShareDataInformationViewController.swift */; }; + E59E8FC32AEA7A81009278F5 /* PurchaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA62AEA7A81009278F5 /* PurchaseViewController.swift */; }; + E59E8FC42AEA7A81009278F5 /* PurchaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA62AEA7A81009278F5 /* PurchaseViewController.swift */; }; + E59E8FC52AEA7A81009278F5 /* TermsAndConditionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA72AEA7A81009278F5 /* TermsAndConditionsViewController.swift */; }; + E59E8FC62AEA7A81009278F5 /* TermsAndConditionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA72AEA7A81009278F5 /* TermsAndConditionsViewController.swift */; }; + E59E8FC72AEA7A81009278F5 /* OptionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA82AEA7A81009278F5 /* OptionsViewController.swift */; }; + E59E8FC82AEA7A81009278F5 /* OptionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E59E8FA82AEA7A81009278F5 /* OptionsViewController.swift */; }; + E5F52A182A8A5D5300828883 /* WifiNetworkMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5F52A172A8A5D5300828883 /* WifiNetworkMonitor.swift */; }; + E5F52A192A8A5D5300828883 /* WifiNetworkMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5F52A172A8A5D5300828883 /* WifiNetworkMonitor.swift */; }; + E5F52A1B2A8A5E1E00828883 /* IPv4Address.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5F52A1A2A8A5E1E00828883 /* IPv4Address.swift */; }; + E5F52A1C2A8A5E1E00828883 /* IPv4Address.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5F52A1A2A8A5E1E00828883 /* IPv4Address.swift */; }; + E5F52A1F2A8A614900828883 /* NetworkMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5F52A1E2A8A614900828883 /* NetworkMonitor.swift */; }; + E5F52A202A8A614900828883 /* NetworkMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5F52A1E2A8A614900828883 /* NetworkMonitor.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -431,6 +582,13 @@ remoteGlobalIDString = 0EFB606F203D7A2C0095398C; remoteInfo = "PIA VPN AdBlocker"; }; + 69CB24A22B051CED00D83A52 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 291C6374183EBC210039EC03 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 291C637B183EBC210039EC03; + remoteInfo = "PIA VPN"; + }; 8269A6E1251CB5E3000B4DBF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 291C6374183EBC210039EC03 /* Project object */; @@ -438,6 +596,20 @@ remoteGlobalIDString = 8269A6D4251CB5E0000B4DBF; remoteInfo = PIAWidgetExtension; }; + AABF827928AE336000CDAC64 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 291C6374183EBC210039EC03 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DDC8F5EB23EC106F005D19C6; + remoteInfo = "PIA VPN WG Tunnel"; + }; + AABF827B28AE336F00CDAC64 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 291C6374183EBC210039EC03 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8269A6D4251CB5E0000B4DBF; + remoteInfo = PIAWidgetExtension; + }; DDC8F5F223EC1070005D19C6 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 291C6374183EBC210039EC03 /* Project object */; @@ -478,6 +650,7 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( + 698F4F2B2AB8A2080010B2B0 /* PIAWidgetExtension.appex in Embed App Extensions */, DD1AB0E923F2993600396E74 /* PIA VPN WG Tunnel.appex in Embed App Extensions */, 0EFB6079203D7A2C0095398C /* PIA VPN AdBlocker.appex in Embed App Extensions */, 0EE220741F4EF307002805AE /* PIA VPN Tunnel.appex in Embed App Extensions */, @@ -488,19 +661,16 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 02823EF3398B7E2C32FA7544 /* Pods_PIA_VPN_Tunnel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PIA_VPN_Tunnel.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 0BE4A5FC9BACD5CAB3D6CEF0 /* Pods-PIA VPN.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PIA VPN.release.xcconfig"; path = "Target Support Files/Pods-PIA VPN/Pods-PIA VPN.release.xcconfig"; sourceTree = ""; }; 0E0715E5201CBB7100D6F666 /* Flags-dev.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Flags-dev.plist"; sourceTree = ""; }; 0E0786DD1EFA7EAE00F77466 /* Components.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Components.plist; sourceTree = ""; }; 0E1F318520176A5F00FC1000 /* Theme+DarkPalette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Theme+DarkPalette.swift"; sourceTree = ""; }; - 0E2215C820084CD700F5FB4D /* SwiftGen+Strings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SwiftGen+Strings.swift"; sourceTree = ""; }; 0E2215CB2008BF8300F5FB4D /* SwiftGen+Assets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SwiftGen+Assets.swift"; sourceTree = ""; }; 0E257AC41DA45D2F0000D3C3 /* NotificationCenter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NotificationCenter.framework; path = System/Library/Frameworks/NotificationCenter.framework; sourceTree = SDKROOT; }; 0E325DA62093277F0020BEDB /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/Main.storyboard; sourceTree = ""; }; 0E392DA51FE3283C0002160D /* TransientState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransientState.swift; sourceTree = ""; }; - 0E3A35271FD9A960000B0F99 /* DashboardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardViewController.swift; sourceTree = ""; }; + 0E3A35271FD9A960000B0F99 /* DashboardViewController.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = DashboardViewController.swift; sourceTree = ""; tabWidth = 4; }; 0E3A352B1FD9CDC5000B0F99 /* Theme+App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Theme+App.swift"; sourceTree = ""; }; - 0E3A35341FD9EBDA000B0F99 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 0E3A35341FD9EBDA000B0F99 /* AppDelegate.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; tabWidth = 4; }; 0E3C9A5D20EC004D00B199F9 /* custom.servers */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = custom.servers; sourceTree = ""; }; 0E441E252055AEDF007528D5 /* ThemeStrategy+App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ThemeStrategy+App.swift"; sourceTree = ""; }; 0E492C661FE60907007F23DF /* Flags.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Flags.swift; sourceTree = ""; }; @@ -558,7 +728,7 @@ 0E9452AA1FDB5EF600891948 /* UINavigationItem+Shortcuts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationItem+Shortcuts.swift"; sourceTree = ""; }; 0E9452AD1FDB5F7A00891948 /* PIAPageControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PIAPageControl.swift; sourceTree = ""; }; 0E9785851DA82FF000711A24 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; - 0E98BB6D1FD5BC6200B41D6B /* Bootstrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bootstrapper.swift; sourceTree = ""; }; + 0E98BB6D1FD5BC6200B41D6B /* Bootstrapper.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = Bootstrapper.swift; sourceTree = ""; tabWidth = 4; }; 0E9AEA6120683FDF00B6E59A /* AboutComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutComponent.swift; sourceTree = ""; }; 0EA660071FEC7A9500CB2B0D /* PIATunnelProvider+UI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PIATunnelProvider+UI.swift"; sourceTree = ""; }; 0EB0A849204F0CE2008BCF1D /* DataCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataCounter.h; sourceTree = ""; }; @@ -594,7 +764,6 @@ 0EFDC1E51FE4ABAA007C0B9B /* Notification+App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+App.swift"; sourceTree = ""; }; 0EFDC1EB1FE4B9DC007C0B9B /* AppConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppConstants.swift; sourceTree = ""; }; 0EFDC1EE1FE4B9E6007C0B9B /* AppConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppConfiguration.swift; sourceTree = ""; }; - 28DFD7434ECA3047EB4A2C75 /* Pods_PIA_VPN_WG_Tunnel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PIA_VPN_WG_Tunnel.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 2909868F18566430002D9687 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 291C637C183EBC210039EC03 /* PIA VPN.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "PIA VPN.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 291C637F183EBC210039EC03 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -612,10 +781,39 @@ 3524670D26B432ED00E3F0AC /* DashboardViewController+ServerSelection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DashboardViewController+ServerSelection.swift"; sourceTree = ""; }; 3545E97F26AAD60C00B812CC /* ServerSelectionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionDelegate.swift; sourceTree = ""; }; 3545E98126AADB2B00B812CC /* ServerSelectingTileCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectingTileCell.swift; sourceTree = ""; }; - 59EC919445EA680B691ACC88 /* Pods-PIA VPNTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PIA VPNTests.debug.xcconfig"; path = "Target Support Files/Pods-PIA VPNTests/Pods-PIA VPNTests.debug.xcconfig"; sourceTree = ""; }; - 678A887CFC02122F4FB83216 /* Pods-PIA VPNTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PIA VPNTests.release.xcconfig"; path = "Target Support Files/Pods-PIA VPNTests/Pods-PIA VPNTests.release.xcconfig"; sourceTree = ""; }; - 6CA493DF6602BFDE96E0E77F /* Pods_PIA_VPN_dev.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PIA_VPN_dev.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 7F6FF659836C1192332662A8 /* Pods-PIA VPN dev.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PIA VPN dev.debug.xcconfig"; path = "Target Support Files/Pods-PIA VPN dev/Pods-PIA VPN dev.debug.xcconfig"; sourceTree = ""; }; + 35EDD6272ADE5D31007B9ACB /* BaseTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseTest.swift; sourceTree = ""; }; + 35EDD6292ADE5F08007B9ACB /* SignInTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInTests.swift; sourceTree = ""; }; + 35EDD6322ADE7281007B9ACB /* OnboardingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingTests.swift; sourceTree = ""; }; + 35EDD6342ADE7424007B9ACB /* VPNPermissionScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNPermissionScreen.swift; sourceTree = ""; }; + 35EDD6362ADE761A007B9ACB /* HomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreen.swift; sourceTree = ""; }; + 35EDD63A2AE62D15007B9ACB /* ElementHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementHelper.swift; sourceTree = ""; }; + 35EDD63D2AE76A3B007B9ACB /* WaitHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitHelper.swift; sourceTree = ""; }; + 35EDD6412AE7A83D007B9ACB /* WelcomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreen.swift; sourceTree = ""; }; + 35EDD6432AE7B480007B9ACB /* Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Common.swift; sourceTree = ""; }; + 35EDD6592B035B51007B9ACB /* SideMenuScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideMenuScreen.swift; sourceTree = ""; }; + 35EDD65B2B047839007B9ACB /* QuickSettingsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSettingsTests.swift; sourceTree = ""; }; + 35EDD65D2B048C68007B9ACB /* QuickSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSettingsScreen.swift; sourceTree = ""; }; + 692483192AB045A5002A0407 /* PIAWidgetAttributes.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = PIAWidgetAttributes.swift; sourceTree = ""; tabWidth = 4; }; + 6924831D2AB04FFD002A0407 /* PIAWidgetBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PIAWidgetBundle.swift; sourceTree = ""; }; + 6924831F2AB05F18002A0407 /* PIAConnectionView.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = PIAConnectionView.swift; sourceTree = ""; tabWidth = 4; }; + 692483212AB05F37002A0407 /* PIACircleIcon.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = PIACircleIcon.swift; sourceTree = ""; tabWidth = 4; }; + 692483252AB05F85002A0407 /* PIAConnectionActivityWidget.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = PIAConnectionActivityWidget.swift; sourceTree = ""; tabWidth = 4; }; + 6947AADB2ACDC8AE001BCC66 /* PIA-VPN-e2e-simulator.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = "PIA-VPN-e2e-simulator.xctestplan"; sourceTree = ""; }; + 698F4F2C2AB978BF0010B2B0 /* PIACircleImageView.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = PIACircleImageView.swift; sourceTree = ""; tabWidth = 4; }; + 698F4F2F2ABA1DA10010B2B0 /* PIAConnectionLiveActivityManager.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = PIAConnectionLiveActivityManager.swift; sourceTree = ""; tabWidth = 4; }; + 699F23AC2AFBA66000EBC5E6 /* SettingsScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsScreen.swift; sourceTree = ""; }; + 699F23AD2AFBA66000EBC5E6 /* HelpSettingsScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HelpSettingsScreen.swift; sourceTree = ""; }; + 699F23AE2AFBA66000EBC5E6 /* AutomationSettingsScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutomationSettingsScreen.swift; sourceTree = ""; }; + 699F23AF2AFBA66000EBC5E6 /* ProtocolsSettingsScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProtocolsSettingsScreen.swift; sourceTree = ""; }; + 699F23B02AFBA66000EBC5E6 /* GeneralSettingsScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneralSettingsScreen.swift; sourceTree = ""; }; + 699F23B12AFBA66000EBC5E6 /* PrivacySettingsScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrivacySettingsScreen.swift; sourceTree = ""; }; + 699F23B82AFBAC0B00EBC5E6 /* UpdateSettingsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdateSettingsTests.swift; sourceTree = ""; }; + 69B70AB02ACBF51C0072A09D /* PIA-VPN_E2E_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "PIA-VPN_E2E_Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 69B70AB42ACBF51C0072A09D /* LoginScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreen.swift; sourceTree = ""; }; + 69B70ABD2ACC2CFE0072A09D /* AccessibilityId.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityId.swift; sourceTree = ""; }; + 69C587FC2AD00C6300B95EF9 /* PIAExampleWithAuthenticatedAppTest.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = PIAExampleWithAuthenticatedAppTest.swift; sourceTree = ""; tabWidth = 2; }; + 7EC2972D27D8B8580061C56A /* CredentialsUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = CredentialsUtil.swift; sourceTree = ""; tabWidth = 4; }; + 7ECBB8DC27B6C4F500C0C774 /* UserSurveyManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSurveyManager.swift; sourceTree = ""; }; 821674F02678A1BE0028E4FD /* SettingsDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDelegate.swift; sourceTree = ""; }; 82183D7A2500FD460033023F /* String+Substrings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Substrings.swift"; sourceTree = ""; }; 82183D9225014FDC0033023F /* NetworkCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NetworkCollectionViewCell.xib; sourceTree = ""; }; @@ -623,7 +821,7 @@ 82183D9425014FDC0033023F /* NetworkFooterCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NetworkFooterCollectionViewCell.xib; sourceTree = ""; }; 82183D9525014FDC0033023F /* PIAHeaderCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PIAHeaderCollectionViewCell.xib; sourceTree = ""; }; 8221922A24CECFE700C24F1C /* NMTTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NMTTests.swift; sourceTree = ""; }; - 822F97B3251DD53100644EF2 /* WidgetUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetUtils.swift; sourceTree = ""; }; + 822F97B3251DD53100644EF2 /* WidgetUserDefaultsDatasource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetUserDefaultsDatasource.swift; sourceTree = ""; }; 824C530724C046CA003DB740 /* ConnectionTile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionTile.swift; sourceTree = ""; }; 824C531324C04796003DB740 /* ConnectionTileCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionTileCollectionViewCell.swift; sourceTree = ""; }; 824C531424C04796003DB740 /* ConnectionTileCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ConnectionTileCollectionViewCell.xib; sourceTree = ""; }; @@ -635,7 +833,7 @@ 8269A6DC251CB5E3000B4DBF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 8269A6DE251CB5E3000B4DBF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 8269A6ED251CB5ED000B4DBF /* PIAWidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PIAWidgetExtension.entitlements; sourceTree = ""; }; - 8269A6FD251CBB36000B4DBF /* WidgetContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetContent.swift; sourceTree = ""; }; + 8269A6FD251CBB36000B4DBF /* WidgetInformation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetInformation.swift; sourceTree = ""; }; 826BE8ED253861BE002339F3 /* DedicatedRegionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DedicatedRegionCell.swift; sourceTree = ""; }; 8272C62626540B2100D846A8 /* ProtocolSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProtocolSettingsViewController.swift; sourceTree = ""; }; 8272C62926551F9B00D846A8 /* SettingPopoverSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SettingPopoverSelectionView.swift; path = Settings/SettingPopoverSelectionView.swift; sourceTree = ""; }; @@ -678,11 +876,14 @@ 82CAB8FC255C115100BB08EF /* MessagesTile.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MessagesTile.xib; sourceTree = ""; }; 82E20B0D24F5666E0065EFE3 /* PIAAccount.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PIAAccount.framework; path = ../account/build/bin/iOS/PIAAccountReleaseFramework/PIAAccount.framework; sourceTree = ""; }; 82F41375264E8AC20098FF4B /* SettingOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingOptions.swift; sourceTree = ""; }; - 8E23999135612F39173E9C1E /* Pods_PIA_VPN.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PIA_VPN.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 9F453DF1F58B8C2676041EDF /* Pods_PIA_VPNTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PIA_VPNTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - A6454C66DD80FE480E48BFA8 /* Pods-PIA VPN WG Tunnel.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PIA VPN WG Tunnel.debug.xcconfig"; path = "Target Support Files/Pods-PIA VPN WG Tunnel/Pods-PIA VPN WG Tunnel.debug.xcconfig"; sourceTree = ""; }; - AC26C61F8D1F24341AD67A4A /* Pods-PIA VPN Tunnel.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PIA VPN Tunnel.release.xcconfig"; path = "Target Support Files/Pods-PIA VPN Tunnel/Pods-PIA VPN Tunnel.release.xcconfig"; sourceTree = ""; }; - B5E30A2B8E23D816328C690E /* Pods-PIA VPN WG Tunnel.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PIA VPN WG Tunnel.release.xcconfig"; path = "Target Support Files/Pods-PIA VPN WG Tunnel/Pods-PIA VPN WG Tunnel.release.xcconfig"; sourceTree = ""; }; + AA52C59E28E5ECD400D025AF /* PIAWidgetVpnDetaislRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PIAWidgetVpnDetaislRow.swift; sourceTree = ""; }; + AAE8789B28E4679500557F26 /* WidgetPersistenceDatasource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetPersistenceDatasource.swift; sourceTree = ""; }; + AAE8789E28E4696300557F26 /* PIAWidgetProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PIAWidgetProvider.swift; sourceTree = ""; }; + AAE878A028E46C1600557F26 /* PIAWidgetPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PIAWidgetPreview.swift; sourceTree = ""; }; + AAE878A228E46D2B00557F26 /* PIAWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PIAWidgetView.swift; sourceTree = ""; }; + AAE878A428E4723B00557F26 /* PIACircleVpnButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PIACircleVpnButton.swift; sourceTree = ""; }; + AAE878A628E473A400557F26 /* PIAWidgetVpnDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PIAWidgetVpnDetailsView.swift; sourceTree = ""; }; + AAE878A828E4765F00557F26 /* PIAIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PIAIconView.swift; sourceTree = ""; }; DD052AC22419003300AD3A24 /* ProtocolTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProtocolTableViewCell.swift; sourceTree = ""; }; DD07AACB242CBFF2000EE1A3 /* AddEmailToAccountViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddEmailToAccountViewController.swift; sourceTree = ""; }; DD125DC421E77046004ECCB6 /* QuickConnectTile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickConnectTile.swift; sourceTree = ""; }; @@ -708,7 +909,6 @@ DD51F8B22372E494009FEED3 /* PIA-RSA-4096.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "PIA-RSA-4096.pem"; sourceTree = ""; }; DD51F8C32372E4C8009FEED3 /* PemUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PemUtil.swift; sourceTree = ""; }; DD522D21237D74380072F555 /* BooleanUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BooleanUtil.swift; sourceTree = ""; }; - DD58F4B721AD579A00D043F7 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; DD58F4BE21B12CFE00D043F7 /* PIAConnectionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PIAConnectionButton.swift; sourceTree = ""; }; DD606AB921C7A17900E0781D /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; DD606ABB21C904BB00E0781D /* PIAHotspotHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PIAHotspotHelper.swift; sourceTree = ""; }; @@ -752,9 +952,100 @@ DDFCFA8E21E892070081F235 /* RegionTileCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RegionTileCollectionViewCell.xib; sourceTree = ""; }; DDFCFA9321E892130081F235 /* RegionTile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegionTile.swift; sourceTree = ""; }; DDFCFA9621E8921F0081F235 /* RegionTile.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RegionTile.xib; sourceTree = ""; }; - E65358880CC5204F785ADE10 /* Pods-PIA VPN Tunnel.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PIA VPN Tunnel.debug.xcconfig"; path = "Target Support Files/Pods-PIA VPN Tunnel/Pods-PIA VPN Tunnel.debug.xcconfig"; sourceTree = ""; }; - EFF4BBB886BD153CAD50F8E2 /* Pods-PIA VPN dev.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PIA VPN dev.release.xcconfig"; path = "Target Support Files/Pods-PIA VPN dev/Pods-PIA VPN dev.release.xcconfig"; sourceTree = ""; }; - F489C6FC39A7285DDE2A26F7 /* Pods-PIA VPN.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PIA VPN.debug.xcconfig"; path = "Target Support Files/Pods-PIA VPN/Pods-PIA VPN.debug.xcconfig"; sourceTree = ""; }; + E501CBB22AE97EBA00515006 /* Signup.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Signup.storyboard; sourceTree = ""; }; + E501CBB52AE97EC800515006 /* Welcome.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Welcome.storyboard; sourceTree = ""; }; + E501CBBB2AE9806800515006 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/UI.strings; sourceTree = ""; }; + E501CBBC2AE9806800515006 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/UI.strings; sourceTree = ""; }; + E501CBBD2AE9806800515006 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/UI.strings"; sourceTree = ""; }; + E501CBBE2AE9806800515006 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/UI.strings; sourceTree = ""; }; + E501CBBF2AE9806800515006 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/UI.strings; sourceTree = ""; }; + E501CBC02AE9806800515006 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/UI.strings; sourceTree = ""; }; + E501CBC12AE9806800515006 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/UI.strings; sourceTree = ""; }; + E501CBC22AE9806800515006 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/UI.strings; sourceTree = ""; }; + E501CBC32AE9806800515006 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/UI.strings; sourceTree = ""; }; + E501CBC42AE9806800515006 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/UI.strings"; sourceTree = ""; }; + E501CBC52AE9806800515006 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/UI.strings; sourceTree = ""; }; + E501CBC62AE9806800515006 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/UI.strings; sourceTree = ""; }; + E501CBC72AE9806800515006 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/UI.strings"; sourceTree = ""; }; + E501CBC82AE9806800515006 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "es-MX.lproj/UI.strings"; sourceTree = ""; }; + E501CBC92AE9806800515006 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/UI.strings; sourceTree = ""; }; + E501CBCA2AE9806800515006 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/UI.strings; sourceTree = ""; }; + E501CBCB2AE9806800515006 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/UI.strings; sourceTree = ""; }; + E501CBCC2AE9806800515006 /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/UI.strings; sourceTree = ""; }; + E501CBCF2AE9806800515006 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Signup.strings; sourceTree = ""; }; + E501CBD12AE9806800515006 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Welcome.strings; sourceTree = ""; }; + E501CBD22AE9806800515006 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Signup.strings; sourceTree = ""; }; + E501CBD32AE9806800515006 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Welcome.strings; sourceTree = ""; }; + E501CBD42AE9806800515006 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Signup.strings"; sourceTree = ""; }; + E501CBD52AE9806800515006 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Welcome.strings"; sourceTree = ""; }; + E501CBD62AE9806800515006 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Signup.strings; sourceTree = ""; }; + E501CBD72AE9806800515006 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Welcome.strings; sourceTree = ""; }; + E501CBD82AE9806800515006 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Signup.strings; sourceTree = ""; }; + E501CBD92AE9806800515006 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Welcome.strings; sourceTree = ""; }; + E501CBDA2AE9806800515006 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Signup.strings; sourceTree = ""; }; + E501CBDB2AE9806800515006 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Welcome.strings; sourceTree = ""; }; + E501CBDC2AE9806800515006 /* UI.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = UI.xcassets; sourceTree = ""; }; + E501CBDD2AE9806800515006 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Signup.strings; sourceTree = ""; }; + E501CBDE2AE9806800515006 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Welcome.strings; sourceTree = ""; }; + E501CBDF2AE9806800515006 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Signup.strings; sourceTree = ""; }; + E501CBE02AE9806800515006 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Welcome.strings; sourceTree = ""; }; + E501CBE12AE9806800515006 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Signup.strings; sourceTree = ""; }; + E501CBE22AE9806800515006 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Welcome.strings; sourceTree = ""; }; + E501CBE32AE9806800515006 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Signup.strings"; sourceTree = ""; }; + E501CBE42AE9806800515006 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Welcome.strings"; sourceTree = ""; }; + E501CBE52AE9806800515006 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Signup.strings; sourceTree = ""; }; + E501CBE62AE9806800515006 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Welcome.strings; sourceTree = ""; }; + E501CBE72AE9806800515006 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Signup.strings; sourceTree = ""; }; + E501CBE82AE9806800515006 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Welcome.strings; sourceTree = ""; }; + E501CBE92AE9806800515006 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Signup.strings"; sourceTree = ""; }; + E501CBEA2AE9806800515006 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Welcome.strings"; sourceTree = ""; }; + E501CBEB2AE9806800515006 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "es-MX.lproj/Signup.strings"; sourceTree = ""; }; + E501CBEC2AE9806800515006 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "es-MX.lproj/Welcome.strings"; sourceTree = ""; }; + E501CBED2AE9806800515006 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Signup.strings; sourceTree = ""; }; + E501CBEE2AE9806800515006 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Welcome.strings; sourceTree = ""; }; + E501CBEF2AE9806800515006 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Signup.strings; sourceTree = ""; }; + E501CBF02AE9806800515006 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Welcome.strings; sourceTree = ""; }; + E501CBF12AE9806800515006 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Signup.strings; sourceTree = ""; }; + E501CBF22AE9806800515006 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Welcome.strings; sourceTree = ""; }; + E501CBF32AE9806800515006 /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/Signup.strings; sourceTree = ""; }; + E501CBF42AE9806800515006 /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/Welcome.strings; sourceTree = ""; }; + E51693C52AFAD3550089FB8F /* UIDevice+WIFI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDevice+WIFI.swift"; sourceTree = ""; }; + E51693D02AFADCC20089FB8F /* SwiftGen+Strings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SwiftGen+Strings.swift"; sourceTree = ""; }; + E51693D42AFBDB8A0089FB8F /* NavigationBar+Appearence..swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NavigationBar+Appearence..swift"; sourceTree = ""; }; + E51693D72AFBE5680089FB8F /* CAGradientLayer+Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CAGradientLayer+Image.swift"; sourceTree = ""; }; + E5217F382AEA7B0E00123442 /* Macros+UI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Macros+UI.swift"; sourceTree = ""; }; + E5217F3B2AEA886000123442 /* BorderedTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BorderedTextField.swift; sourceTree = ""; }; + E5217F3E2AEAC7A900123442 /* Theme+LightPalette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Theme+LightPalette.swift"; sourceTree = ""; }; + E5217F3F2AEAC7A900123442 /* Theme.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; }; + E5217F442AEACE0200123442 /* NavigationLogoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationLogoView.swift; sourceTree = ""; }; + E5217F472AEAD28000123442 /* UIViewLoading.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewLoading.swift; sourceTree = ""; }; + E5217F4A2AEAD29F00123442 /* PurchasePlanCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PurchasePlanCell.swift; sourceTree = ""; }; + E5217F532AEAD54600123442 /* WalkthroughPageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalkthroughPageView.swift; sourceTree = ""; }; + E5217F5C2AEAE01400123442 /* NotificationCategory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationCategory.swift; sourceTree = ""; }; + E5217F652AEAF94C00123442 /* SwiftGen+Assets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SwiftGen+Assets.swift"; sourceTree = ""; }; + E5217F6E2AEB042800123442 /* ClientError+Localization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ClientError+Localization.swift"; sourceTree = ""; }; + E5217F712AEB055D00123442 /* Client+Storyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Client+Storyboard.swift"; sourceTree = ""; }; + E59E8F932AEA7A29009278F5 /* ActivityButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityButton.swift; sourceTree = ""; }; + E59E8F962AEA7A5A009278F5 /* AutolayoutViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutolayoutViewController.swift; sourceTree = ""; }; + E59E8F992AEA7A7F009278F5 /* SignupInternetUnreachableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignupInternetUnreachableViewController.swift; sourceTree = ""; }; + E59E8F9A2AEA7A7F009278F5 /* SignupSuccessViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignupSuccessViewController.swift; sourceTree = ""; }; + E59E8F9B2AEA7A7F009278F5 /* SignupInProgressViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignupInProgressViewController.swift; sourceTree = ""; }; + E59E8F9C2AEA7A80009278F5 /* MagicLinkLoginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MagicLinkLoginViewController.swift; sourceTree = ""; }; + E59E8F9D2AEA7A80009278F5 /* LoginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginViewController.swift; sourceTree = ""; }; + E59E8F9E2AEA7A80009278F5 /* PIAWelcomeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PIAWelcomeViewController.swift; sourceTree = ""; }; + E59E8F9F2AEA7A80009278F5 /* GetStartedViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetStartedViewController.swift; sourceTree = ""; }; + E59E8FA02AEA7A80009278F5 /* ConfirmVPNPlanViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfirmVPNPlanViewController.swift; sourceTree = ""; }; + E59E8FA12AEA7A80009278F5 /* RestoreSignupViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RestoreSignupViewController.swift; sourceTree = ""; }; + E59E8FA22AEA7A80009278F5 /* GDPRViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GDPRViewController.swift; sourceTree = ""; }; + E59E8FA32AEA7A80009278F5 /* SignupFailureViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignupFailureViewController.swift; sourceTree = ""; }; + E59E8FA42AEA7A80009278F5 /* WelcomePageViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomePageViewController.swift; sourceTree = ""; }; + E59E8FA52AEA7A81009278F5 /* ShareDataInformationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShareDataInformationViewController.swift; sourceTree = ""; }; + E59E8FA62AEA7A81009278F5 /* PurchaseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PurchaseViewController.swift; sourceTree = ""; }; + E59E8FA72AEA7A81009278F5 /* TermsAndConditionsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TermsAndConditionsViewController.swift; sourceTree = ""; }; + E59E8FA82AEA7A81009278F5 /* OptionsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionsViewController.swift; sourceTree = ""; }; + E5F52A172A8A5D5300828883 /* WifiNetworkMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WifiNetworkMonitor.swift; sourceTree = ""; }; + E5F52A1A2A8A5E1E00828883 /* IPv4Address.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPv4Address.swift; sourceTree = ""; }; + E5F52A1E2A8A614900828883 /* NetworkMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkMonitor.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -762,7 +1053,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 3732E0F0C64DA8513903087D /* Pods_PIA_VPN_Tunnel.framework in Frameworks */, + 697C59B02AFD0791008B6212 /* PIALibrary in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -770,16 +1061,23 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + AABF827128AD188700CDAC64 /* AlamofireImage in Frameworks */, + AABF827628AE302300CDAC64 /* NetworkExtension.framework in Frameworks */, 0EE220571F4EF307002805AE /* Security.framework in Frameworks */, 0EE220581F4EF307002805AE /* SystemConfiguration.framework in Frameworks */, + AABF827328AE2FF500CDAC64 /* GradientProgressBar in Frameworks */, + AABF827828AE333200CDAC64 /* DZNEmptyDataSet in Frameworks */, 0EE220591F4EF307002805AE /* libz.dylib in Frameworks */, 0EE2205A1F4EF307002805AE /* CoreText.framework in Frameworks */, 0EE2205B1F4EF307002805AE /* QuartzCore.framework in Frameworks */, 0EE2205C1F4EF307002805AE /* CoreGraphics.framework in Frameworks */, + AABF826F28AD187800CDAC64 /* Popover in Frameworks */, + 0EE2205F1F4EF307002805AE /* StoreKit.framework in Frameworks */, + 697C59AE2AFD0786008B6212 /* PIALibrary in Frameworks */, 0EE2205D1F4EF307002805AE /* UIKit.framework in Frameworks */, 0EE2205E1F4EF307002805AE /* Foundation.framework in Frameworks */, - 0EE2205F1F4EF307002805AE /* StoreKit.framework in Frameworks */, - 12CE273914ED9E7533E3A51E /* Pods_PIA_VPN_dev.framework in Frameworks */, + AABF826D28AD185E00CDAC64 /* TweetNacl in Frameworks */, + AABF827528AE2FFE00CDAC64 /* SideMenu in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -787,7 +1085,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 929703E310E04502651A34E9 /* Pods_PIA_VPNTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -802,6 +1099,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + AA36CDC428A6711300180A33 /* Popover in Frameworks */, + AA36CDCC28A673C900180A33 /* GradientProgressBar in Frameworks */, + AA36CDCF28A6746500180A33 /* SideMenu in Frameworks */, + AA36CDBB28A6622A00180A33 /* TweetNacl in Frameworks */, + AA36CDDE28A6878000180A33 /* AlamofireImage in Frameworks */, 2909869018566430002D9687 /* Security.framework in Frameworks */, 299E58511856BD31004CFD63 /* SystemConfiguration.framework in Frameworks */, 299E585F1856C6EE004CFD63 /* libz.dylib in Frameworks */, @@ -809,10 +1111,20 @@ 2985E5671856BD1200D70E28 /* QuartzCore.framework in Frameworks */, 291C6382183EBC210039EC03 /* CoreGraphics.framework in Frameworks */, 291C6384183EBC210039EC03 /* UIKit.framework in Frameworks */, + 697C59AC2AFD0771008B6212 /* PIALibrary in Frameworks */, DD606ABA21C7A17900E0781D /* NetworkExtension.framework in Frameworks */, + AA36CDC928A6733500180A33 /* DZNEmptyDataSet in Frameworks */, 291C6380183EBC210039EC03 /* Foundation.framework in Frameworks */, 0E9785861DA82FF000711A24 /* StoreKit.framework in Frameworks */, - 73E0B0544DF023785B11C4B9 /* Pods_PIA_VPN.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 69B70AAD2ACBF51C0072A09D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 35950B312ADD2996006F3CD9 /* Quick in Frameworks */, + 35950B342ADD2EE5006F3CD9 /* Nimble in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -829,8 +1141,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 697C59B22AFD079B008B6212 /* PIALibrary in Frameworks */, + AA36CDDB28A6860F00180A33 /* TweetNacl in Frameworks */, DDC8F5F923EC10E4005D19C6 /* NetworkExtension.framework in Frameworks */, - 078FA875634A84BD6728DF93 /* Pods_PIA_VPN_WG_Tunnel.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -946,6 +1259,7 @@ 0E76AE201D35447A00421248 /* Utils */ = { isa = PBXGroup; children = ( + E5F52A1D2A8A613400828883 /* Network */, 0EB0A849204F0CE2008BCF1D /* DataCounter.h */, 0EB0A84A204F0CE2008BCF1D /* DataCounter.m */, 0EB0A84B204F0CE2008BCF1D /* DataCounter.swift */, @@ -958,9 +1272,11 @@ DD51F8C32372E4C8009FEED3 /* PemUtil.swift */, DD522D21237D74380072F555 /* BooleanUtil.swift */, DD918575246BFA7F006B3A2B /* RatingManager.swift */, + 7ECBB8DC27B6C4F500C0C774 /* UserSurveyManager.swift */, DDD65312247E66AD00F0A897 /* CoordinatesFinder.swift */, 829EB51B2535A8FF003E74DD /* CollectionViewAutoSizeUtils.swift */, 3524670A26B431B800E3F0AC /* TrustedNetworkHelper.swift */, + E51693C52AFAD3550089FB8F /* UIDevice+WIFI.swift */, ); name = Utils; sourceTree = ""; @@ -1012,6 +1328,7 @@ 0EEE1C191E4F719E00397DE2 /* Resources */ = { isa = PBXGroup; children = ( + E501CBB82AE9806800515006 /* Resources */, DD51F8B02372E494009FEED3 /* PublicCerts */, DD4368A3224A73E4005D373B /* UI */, DD6DC5C021B6C27F00F9D538 /* Lottie */, @@ -1019,7 +1336,6 @@ 0E0786DD1EFA7EAE00F77466 /* Components.plist */, 0E3C9A5D20EC004D00B199F9 /* custom.servers */, 0ED66BCF20A9918000333B35 /* staging.endpoint */, - DD58F4B721AD579A00D043F7 /* GoogleService-Info.plist */, ); path = Resources; sourceTree = ""; @@ -1045,9 +1361,9 @@ 0EEE1C191E4F719E00397DE2 /* Resources */, DDC8F5ED23EC1070005D19C6 /* PIA VPN WG Tunnel */, 8269A6D8251CB5E0000B4DBF /* PIAWidget */, + 69B70AB12ACBF51C0072A09D /* PIA-VPN_E2E_Tests */, 291C637E183EBC210039EC03 /* Frameworks */, 291C637D183EBC210039EC03 /* Products */, - 90B2842B07AEDA4CF8A2035B /* Pods */, ); sourceTree = ""; }; @@ -1061,6 +1377,7 @@ 0EFB6070203D7A2C0095398C /* PIA VPN AdBlocker.appex */, DDC8F5EC23EC106F005D19C6 /* PIA VPN WG Tunnel.appex */, 8269A6D5251CB5E0000B4DBF /* PIAWidgetExtension.appex */, + 69B70AB02ACBF51C0072A09D /* PIA-VPN_E2E_Tests.xctest */, ); name = Products; sourceTree = ""; @@ -1085,11 +1402,6 @@ 0E257AC41DA45D2F0000D3C3 /* NotificationCenter.framework */, 8269A67C251CB4BA000B4DBF /* WidgetKit.framework */, 8269A67E251CB4BA000B4DBF /* SwiftUI.framework */, - 8E23999135612F39173E9C1E /* Pods_PIA_VPN.framework */, - 02823EF3398B7E2C32FA7544 /* Pods_PIA_VPN_Tunnel.framework */, - 28DFD7434ECA3047EB4A2C75 /* Pods_PIA_VPN_WG_Tunnel.framework */, - 6CA493DF6602BFDE96E0E77F /* Pods_PIA_VPN_dev.framework */, - 9F453DF1F58B8C2676041EDF /* Pods_PIA_VPNTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -1136,15 +1448,18 @@ 296B7BB21A1840CB005606AD /* Shared */ = { isa = PBXGroup; children = ( + E5217F6E2AEB042800123442 /* ClientError+Localization.swift */, 0E9452981FDB4DF500891948 /* GradientView.swift */, 0EE14D171FF15812008D9AC2 /* ModalNavigationSegue.swift */, 0E9452AD1FDB5F7A00891948 /* PIAPageControl.swift */, 0E2215CB2008BF8300F5FB4D /* SwiftGen+Assets.swift */, + E5217F652AEAF94C00123442 /* SwiftGen+Assets.swift */, DDC8124B2176185000CB290C /* SwiftGen+SeguesStoryboards.swift */, DDC8124E21761B0B00CB290C /* SwiftGen+ScenesStoryboards.swift */, - 0E2215C820084CD700F5FB4D /* SwiftGen+Strings.swift */, + E51693D02AFADCC20089FB8F /* SwiftGen+Strings.swift */, DD58F4BE21B12CFE00D043F7 /* PIAConnectionButton.swift */, DD125DD021E7A694004ECCB6 /* ServerButton.swift */, + 69B70ABD2ACC2CFE0072A09D /* AccessibilityId.swift */, ); name = Shared; sourceTree = ""; @@ -1152,15 +1467,123 @@ 296BBFEE1840066A00944151 /* UI */ = { isa = PBXGroup; children = ( + E5217F5C2AEAE01400123442 /* NotificationCategory.swift */, + E5217F532AEAD54600123442 /* WalkthroughPageView.swift */, + E5217F4A2AEAD29F00123442 /* PurchasePlanCell.swift */, + E5217F472AEAD28000123442 /* UIViewLoading.swift */, + E5217F442AEACE0200123442 /* NavigationLogoView.swift */, + E5217F3F2AEAC7A900123442 /* Theme.swift */, + E5217F3E2AEAC7A900123442 /* Theme+LightPalette.swift */, + E5217F382AEA7B0E00123442 /* Macros+UI.swift */, + E59E8FA02AEA7A80009278F5 /* ConfirmVPNPlanViewController.swift */, + E59E8FA22AEA7A80009278F5 /* GDPRViewController.swift */, + E59E8F9F2AEA7A80009278F5 /* GetStartedViewController.swift */, + E59E8F9D2AEA7A80009278F5 /* LoginViewController.swift */, + E59E8F9C2AEA7A80009278F5 /* MagicLinkLoginViewController.swift */, + E59E8FA82AEA7A81009278F5 /* OptionsViewController.swift */, + E59E8F9E2AEA7A80009278F5 /* PIAWelcomeViewController.swift */, + E59E8FA62AEA7A81009278F5 /* PurchaseViewController.swift */, + E59E8FA12AEA7A80009278F5 /* RestoreSignupViewController.swift */, + E59E8FA52AEA7A81009278F5 /* ShareDataInformationViewController.swift */, + E59E8FA32AEA7A80009278F5 /* SignupFailureViewController.swift */, + E59E8F9B2AEA7A7F009278F5 /* SignupInProgressViewController.swift */, + E59E8F992AEA7A7F009278F5 /* SignupInternetUnreachableViewController.swift */, + E59E8F9A2AEA7A7F009278F5 /* SignupSuccessViewController.swift */, + E59E8FA72AEA7A81009278F5 /* TermsAndConditionsViewController.swift */, + E59E8FA42AEA7A80009278F5 /* WelcomePageViewController.swift */, + E59E8F962AEA7A5A009278F5 /* AutolayoutViewController.swift */, + E59E8F932AEA7A29009278F5 /* ActivityButton.swift */, + E5217F3B2AEA886000123442 /* BorderedTextField.swift */, 82F41374264E8AAD0098FF4B /* Settings */, 82A1AD2424B86ADB0003DD02 /* Cards */, 0E1CFCBD1EBB9F040073155D /* Dashboard */, 0E1CFCBE1EBB9F860073155D /* Menu */, 296B7BB21A1840CB005606AD /* Shared */, + E5217F712AEB055D00123442 /* Client+Storyboard.swift */, + E51693D42AFBDB8A0089FB8F /* NavigationBar+Appearence..swift */, + E51693D72AFBE5680089FB8F /* CAGradientLayer+Image.swift */, ); name = UI; sourceTree = ""; }; + 35EDD6262ADE5D1E007B9ACB /* Tests */ = { + isa = PBXGroup; + children = ( + 699F23B82AFBAC0B00EBC5E6 /* UpdateSettingsTests.swift */, + 69C587FC2AD00C6300B95EF9 /* PIAExampleWithAuthenticatedAppTest.swift */, + 35EDD6292ADE5F08007B9ACB /* SignInTests.swift */, + 35EDD6322ADE7281007B9ACB /* OnboardingTests.swift */, + 35EDD65B2B047839007B9ACB /* QuickSettingsTests.swift */, + ); + path = Tests; + sourceTree = ""; + }; + 35EDD62B2ADE62FE007B9ACB /* Screens */ = { + isa = PBXGroup; + children = ( + 699F23AB2AFBA66000EBC5E6 /* Settings */, + 69B70AB42ACBF51C0072A09D /* LoginScreen.swift */, + 35EDD6342ADE7424007B9ACB /* VPNPermissionScreen.swift */, + 35EDD6362ADE761A007B9ACB /* HomeScreen.swift */, + 35EDD6412AE7A83D007B9ACB /* WelcomeScreen.swift */, + 35EDD6432AE7B480007B9ACB /* Common.swift */, + 35EDD6592B035B51007B9ACB /* SideMenuScreen.swift */, + ); + path = Screens; + sourceTree = ""; + }; + 35EDD6382AE62CF0007B9ACB /* Helpers */ = { + isa = PBXGroup; + children = ( + 35EDD63A2AE62D15007B9ACB /* ElementHelper.swift */, + 35EDD63D2AE76A3B007B9ACB /* WaitHelper.swift */, + ); + path = Helpers; + sourceTree = ""; + }; + 35EDD63C2AE7679B007B9ACB /* Core */ = { + isa = PBXGroup; + children = ( + 35EDD6272ADE5D31007B9ACB /* BaseTest.swift */, + ); + path = Core; + sourceTree = ""; + }; + 699F23AB2AFBA66000EBC5E6 /* Settings */ = { + isa = PBXGroup; + children = ( + 699F23AC2AFBA66000EBC5E6 /* SettingsScreen.swift */, + 699F23AD2AFBA66000EBC5E6 /* HelpSettingsScreen.swift */, + 699F23AE2AFBA66000EBC5E6 /* AutomationSettingsScreen.swift */, + 699F23AF2AFBA66000EBC5E6 /* ProtocolsSettingsScreen.swift */, + 699F23B02AFBA66000EBC5E6 /* GeneralSettingsScreen.swift */, + 699F23B12AFBA66000EBC5E6 /* PrivacySettingsScreen.swift */, + 35EDD65D2B048C68007B9ACB /* QuickSettingsScreen.swift */, + ); + path = Settings; + sourceTree = ""; + }; + 69B70AB12ACBF51C0072A09D /* PIA-VPN_E2E_Tests */ = { + isa = PBXGroup; + children = ( + 35EDD63C2AE7679B007B9ACB /* Core */, + 35EDD6382AE62CF0007B9ACB /* Helpers */, + 35EDD62B2ADE62FE007B9ACB /* Screens */, + 35EDD6262ADE5D1E007B9ACB /* Tests */, + 6947AADB2ACDC8AE001BCC66 /* PIA-VPN-e2e-simulator.xctestplan */, + 69D12D152ACC75140053A81B /* Util */, + ); + path = "PIA-VPN_E2E_Tests"; + sourceTree = ""; + }; + 69D12D152ACC75140053A81B /* Util */ = { + isa = PBXGroup; + children = ( + 7EC2972D27D8B8580061C56A /* CredentialsUtil.swift */, + ); + path = Util; + sourceTree = ""; + }; 82183D8425014F940033023F /* Menu */ = { isa = PBXGroup; children = ( @@ -1187,9 +1610,8 @@ 8269A6D8251CB5E0000B4DBF /* PIAWidget */ = { isa = PBXGroup; children = ( - 8269A6D9251CB5E0000B4DBF /* PIAWidget.swift */, - 8269A6FD251CBB36000B4DBF /* WidgetContent.swift */, - 822F97B3251DD53100644EF2 /* WidgetUtils.swift */, + AAE8789728E45C6200557F26 /* Data */, + AAE8789628E45C5D00557F26 /* Domain */, 82BAACFD25B09C9200B3C733 /* PIAWidget.intentdefinition */, 8269A6DC251CB5E3000B4DBF /* Assets.xcassets */, 8269A6DE251CB5E3000B4DBF /* Info.plist */, @@ -1243,21 +1665,68 @@ name = Settings; sourceTree = ""; }; - 90B2842B07AEDA4CF8A2035B /* Pods */ = { + AAE8789628E45C5D00557F26 /* Domain */ = { isa = PBXGroup; children = ( - F489C6FC39A7285DDE2A26F7 /* Pods-PIA VPN.debug.xcconfig */, - 0BE4A5FC9BACD5CAB3D6CEF0 /* Pods-PIA VPN.release.xcconfig */, - E65358880CC5204F785ADE10 /* Pods-PIA VPN Tunnel.debug.xcconfig */, - AC26C61F8D1F24341AD67A4A /* Pods-PIA VPN Tunnel.release.xcconfig */, - A6454C66DD80FE480E48BFA8 /* Pods-PIA VPN WG Tunnel.debug.xcconfig */, - B5E30A2B8E23D816328C690E /* Pods-PIA VPN WG Tunnel.release.xcconfig */, - 7F6FF659836C1192332662A8 /* Pods-PIA VPN dev.debug.xcconfig */, - EFF4BBB886BD153CAD50F8E2 /* Pods-PIA VPN dev.release.xcconfig */, - 59EC919445EA680B691ACC88 /* Pods-PIA VPNTests.debug.xcconfig */, - 678A887CFC02122F4FB83216 /* Pods-PIA VPNTests.release.xcconfig */, + AAE8789D28E468F400557F26 /* Widget */, + AAE8789A28E45EC500557F26 /* UI */, ); - path = Pods; + path = Domain; + sourceTree = ""; + }; + AAE8789728E45C6200557F26 /* Data */ = { + isa = PBXGroup; + children = ( + AAE8789928E45DDE00557F26 /* Model */, + AAE8789828E45DD500557F26 /* Cache */, + ); + path = Data; + sourceTree = ""; + }; + AAE8789828E45DD500557F26 /* Cache */ = { + isa = PBXGroup; + children = ( + 822F97B3251DD53100644EF2 /* WidgetUserDefaultsDatasource.swift */, + AAE8789B28E4679500557F26 /* WidgetPersistenceDatasource.swift */, + ); + path = Cache; + sourceTree = ""; + }; + AAE8789928E45DDE00557F26 /* Model */ = { + isa = PBXGroup; + children = ( + 8269A6FD251CBB36000B4DBF /* WidgetInformation.swift */, + ); + path = Model; + sourceTree = ""; + }; + AAE8789A28E45EC500557F26 /* UI */ = { + isa = PBXGroup; + children = ( + AAE878A228E46D2B00557F26 /* PIAWidgetView.swift */, + AAE878A428E4723B00557F26 /* PIACircleVpnButton.swift */, + AAE878A628E473A400557F26 /* PIAWidgetVpnDetailsView.swift */, + AAE878A828E4765F00557F26 /* PIAIconView.swift */, + AA52C59E28E5ECD400D025AF /* PIAWidgetVpnDetaislRow.swift */, + 6924831F2AB05F18002A0407 /* PIAConnectionView.swift */, + 692483212AB05F37002A0407 /* PIACircleIcon.swift */, + 698F4F2C2AB978BF0010B2B0 /* PIACircleImageView.swift */, + ); + path = UI; + sourceTree = ""; + }; + AAE8789D28E468F400557F26 /* Widget */ = { + isa = PBXGroup; + children = ( + 8269A6D9251CB5E0000B4DBF /* PIAWidget.swift */, + AAE8789E28E4696300557F26 /* PIAWidgetProvider.swift */, + AAE878A028E46C1600557F26 /* PIAWidgetPreview.swift */, + 692483192AB045A5002A0407 /* PIAWidgetAttributes.swift */, + 6924831D2AB04FFD002A0407 /* PIAWidgetBundle.swift */, + 692483252AB05F85002A0407 /* PIAConnectionActivityWidget.swift */, + 698F4F2F2ABA1DA10010B2B0 /* PIAConnectionLiveActivityManager.swift */, + ); + path = Widget; sourceTree = ""; }; DD1C137E21E6073A004004B3 /* Tiles */ = { @@ -1305,6 +1774,8 @@ DD4368A4224A73F1005D373B /* Core */, 0ECB081F1D61D2A900043852 /* Launch Screen.storyboard */, 291C6391183EBC210039EC03 /* Main.storyboard */, + E501CBB22AE97EBA00515006 /* Signup.storyboard */, + E501CBB52AE97EC800515006 /* Welcome.storyboard */, ); path = UI; sourceTree = ""; @@ -1396,6 +1867,51 @@ path = "PIA VPN WG Tunnel"; sourceTree = ""; }; + E501CBB82AE9806800515006 /* Resources */ = { + isa = PBXGroup; + children = ( + E501CBB92AE9806800515006 /* Shared */, + E501CBCD2AE9806800515006 /* iOS */, + ); + path = Resources; + sourceTree = ""; + }; + E501CBB92AE9806800515006 /* Shared */ = { + isa = PBXGroup; + children = ( + E501CBBA2AE9806800515006 /* UI.strings */, + ); + path = Shared; + sourceTree = ""; + }; + E501CBCD2AE9806800515006 /* iOS */ = { + isa = PBXGroup; + children = ( + E501CBCE2AE9806800515006 /* Signup.strings */, + E501CBD02AE9806800515006 /* Welcome.strings */, + E501CBDC2AE9806800515006 /* UI.xcassets */, + ); + path = iOS; + sourceTree = ""; + }; + E5F52A162A8A5D3800828883 /* Wifi */ = { + isa = PBXGroup; + children = ( + E5F52A172A8A5D5300828883 /* WifiNetworkMonitor.swift */, + ); + name = Wifi; + sourceTree = ""; + }; + E5F52A1D2A8A613400828883 /* Network */ = { + isa = PBXGroup; + children = ( + E5F52A162A8A5D3800828883 /* Wifi */, + E5F52A1A2A8A5E1E00828883 /* IPv4Address.swift */, + E5F52A1E2A8A614900828883 /* NetworkMonitor.swift */, + ); + name = Network; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1403,7 +1919,6 @@ isa = PBXNativeTarget; buildConfigurationList = 0E67FC2E1E3F802D00EF9929 /* Build configuration list for PBXNativeTarget "PIA VPN Tunnel" */; buildPhases = ( - 5FDBE92B797C696CA4F5D6E3 /* [CP] Check Pods Manifest.lock */, 0E67FC1E1E3F802D00EF9929 /* Sources */, 0E67FC1F1E3F802D00EF9929 /* Frameworks */, 0E67FC201E3F802D00EF9929 /* Resources */, @@ -1413,6 +1928,9 @@ dependencies = ( ); name = "PIA VPN Tunnel"; + packageProductDependencies = ( + 697C59AF2AFD0791008B6212 /* PIALibrary */, + ); productName = "PIA OpenVPN"; productReference = 0E67FC221E3F802D00EF9929 /* PIA VPN Tunnel.appex */; productType = "com.apple.product-type.app-extension"; @@ -1421,7 +1939,6 @@ isa = PBXNativeTarget; buildConfigurationList = 0EE220771F4EF307002805AE /* Build configuration list for PBXNativeTarget "PIA VPN dev" */; buildPhases = ( - C26EC034B9AB0A02D7164F82 /* [CP] Check Pods Manifest.lock */, 0EF9ABF71FF792DD005E1418 /* SwiftGen */, 0EE2200F1F4EF307002805AE /* Sources */, 0EE220561F4EF307002805AE /* Frameworks */, @@ -1429,16 +1946,25 @@ 0EE220711F4EF307002805AE /* Download Latest Regions List */, 0EE220731F4EF307002805AE /* Embed App Extensions */, 0E60FF9E1F4F50A2001D30DB /* Embed Frameworks */, - DD58F4B921AE84B300D043F7 /* ShellScript */, - DA22F2CE535A37D07F2DE296 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); dependencies = ( 0EE2200C1F4EF307002805AE /* PBXTargetDependency */, 0EFB6078203D7A2C0095398C /* PBXTargetDependency */, + AABF827A28AE336000CDAC64 /* PBXTargetDependency */, + AABF827C28AE336F00CDAC64 /* PBXTargetDependency */, ); name = "PIA VPN dev"; + packageProductDependencies = ( + AABF826C28AD185E00CDAC64 /* TweetNacl */, + AABF826E28AD187800CDAC64 /* Popover */, + AABF827028AD188700CDAC64 /* AlamofireImage */, + AABF827228AE2FF500CDAC64 /* GradientProgressBar */, + AABF827428AE2FFE00CDAC64 /* SideMenu */, + AABF827728AE333200CDAC64 /* DZNEmptyDataSet */, + 697C59AD2AFD0786008B6212 /* PIALibrary */, + ); productName = "PIA VPN"; productReference = 0EE2207A1F4EF307002805AE /* PIA VPN dev.app */; productType = "com.apple.product-type.application"; @@ -1447,11 +1973,9 @@ isa = PBXNativeTarget; buildConfigurationList = 0EEE1BF01E4F6EF400397DE2 /* Build configuration list for PBXNativeTarget "PIA VPNTests" */; buildPhases = ( - B6830C11847908188577F5A5 /* [CP] Check Pods Manifest.lock */, 0EEE1BE31E4F6EF400397DE2 /* Sources */, 0EEE1BE41E4F6EF400397DE2 /* Frameworks */, 0EEE1BE51E4F6EF400397DE2 /* Resources */, - 6B3D203586AD5EDAB8192C77 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -1485,13 +2009,11 @@ isa = PBXNativeTarget; buildConfigurationList = 291C63AE183EBC220039EC03 /* Build configuration list for PBXNativeTarget "PIA VPN" */; buildPhases = ( - 11E8771AD2F21EF4B428154B /* [CP] Check Pods Manifest.lock */, 291C6378183EBC210039EC03 /* Sources */, 291C6379183EBC210039EC03 /* Frameworks */, 291C637A183EBC210039EC03 /* Resources */, 2931563B18513F6500E769A7 /* Download Latest Regions List */, 0E98CF0E1DCBFB3B003F1986 /* Embed App Extensions */, - 7103EE1907DBBDBB001EC846 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -1502,10 +2024,41 @@ 8269A6E2251CB5E3000B4DBF /* PBXTargetDependency */, ); name = "PIA VPN"; + packageProductDependencies = ( + AA36CDBA28A6622A00180A33 /* TweetNacl */, + AA36CDC328A6711300180A33 /* Popover */, + AA36CDC828A6733500180A33 /* DZNEmptyDataSet */, + AA36CDCB28A673C900180A33 /* GradientProgressBar */, + AA36CDCE28A6746500180A33 /* SideMenu */, + AA36CDDD28A6878000180A33 /* AlamofireImage */, + 697C59AB2AFD0770008B6212 /* PIALibrary */, + ); productName = "PIA VPN"; productReference = 291C637C183EBC210039EC03 /* PIA VPN.app */; productType = "com.apple.product-type.application"; }; + 69B70AAF2ACBF51C0072A09D /* PIA-VPN_E2E_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 69B70ABA2ACBF51C0072A09D /* Build configuration list for PBXNativeTarget "PIA-VPN_E2E_Tests" */; + buildPhases = ( + 69B70AAC2ACBF51C0072A09D /* Sources */, + 69B70AAD2ACBF51C0072A09D /* Frameworks */, + 69B70AAE2ACBF51C0072A09D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 69CB24A32B051CED00D83A52 /* PBXTargetDependency */, + ); + name = "PIA-VPN_E2E_Tests"; + packageProductDependencies = ( + 35950B302ADD2996006F3CD9 /* Quick */, + 35950B332ADD2EE5006F3CD9 /* Nimble */, + ); + productName = "PIA-VPN_E2E_Tests"; + productReference = 69B70AB02ACBF51C0072A09D /* PIA-VPN_E2E_Tests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; 8269A6D4251CB5E0000B4DBF /* PIAWidgetExtension */ = { isa = PBXNativeTarget; buildConfigurationList = 8269A6E4251CB5E3000B4DBF /* Build configuration list for PBXNativeTarget "PIAWidgetExtension" */; @@ -1527,7 +2080,6 @@ isa = PBXNativeTarget; buildConfigurationList = DDC8F5F723EC1070005D19C6 /* Build configuration list for PBXNativeTarget "PIA VPN WG Tunnel" */; buildPhases = ( - 31FE519987479E33FFCDAB88 /* [CP] Check Pods Manifest.lock */, DDC8F5E823EC106F005D19C6 /* Sources */, DDC8F5E923EC106F005D19C6 /* Frameworks */, DDC8F5EA23EC106F005D19C6 /* Resources */, @@ -1537,6 +2089,10 @@ dependencies = ( ); name = "PIA VPN WG Tunnel"; + packageProductDependencies = ( + AA36CDDA28A6860F00180A33 /* TweetNacl */, + 697C59B12AFD079B008B6212 /* PIALibrary */, + ); productName = "PIA VPN WG Tunnel"; productReference = DDC8F5EC23EC106F005D19C6 /* PIA VPN WG Tunnel.appex */; productType = "com.apple.product-type.app-extension"; @@ -1548,7 +2104,7 @@ isa = PBXProject; attributes = { CLASSPREFIX = PIA; - LastSwiftUpdateCheck = 1200; + LastSwiftUpdateCheck = 1430; LastUpgradeCheck = 0930; ORGANIZATIONNAME = "Private Internet Access Inc."; TargetAttributes = { @@ -1576,9 +2132,7 @@ }; 0EEE1BE61E4F6EF400397DE2 = { CreatedOnToolsVersion = 8.2.1; - DevelopmentTeam = 5357M5NW9W; LastSwiftMigration = 1010; - ProvisioningStyle = Automatic; TestTargetID = 291C637B183EBC210039EC03; }; 0EFB606F203D7A2C0095398C = { @@ -1620,6 +2174,10 @@ }; }; }; + 69B70AAF2ACBF51C0072A09D = { + CreatedOnToolsVersion = 14.3.1; + TestTargetID = 291C637B183EBC210039EC03; + }; 8269A6D4251CB5E0000B4DBF = { CreatedOnToolsVersion = 12.0; DevelopmentTeam = 5357M5NW9W; @@ -1658,6 +2216,17 @@ Base, ); mainGroup = 291C6373183EBC210039EC03; + packageReferences = ( + AA36CDB928A6622A00180A33 /* XCRemoteSwiftPackageReference "tweetnacl-swiftwrap" */, + AA36CDC228A6711300180A33 /* XCRemoteSwiftPackageReference "Popover" */, + AA36CDC728A6733500180A33 /* XCRemoteSwiftPackageReference "DZNEmptyDataSet" */, + AA36CDCA28A673C900180A33 /* XCRemoteSwiftPackageReference "GradientProgressBar" */, + AA36CDCD28A6746500180A33 /* XCRemoteSwiftPackageReference "SideMenu" */, + AA36CDDC28A6878000180A33 /* XCRemoteSwiftPackageReference "AlamofireImage" */, + 35950B2F2ADD2877006F3CD9 /* XCRemoteSwiftPackageReference "Quick" */, + 35950B322ADD2EE5006F3CD9 /* XCRemoteSwiftPackageReference "Nimble" */, + 697C59AA2AFD0770008B6212 /* XCRemoteSwiftPackageReference "mobile-ios-library" */, + ); productRefGroup = 291C637D183EBC210039EC03 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -1669,6 +2238,7 @@ DDC8F5EB23EC106F005D19C6 /* PIA VPN WG Tunnel */, 8269A6D4251CB5E0000B4DBF /* PIAWidgetExtension */, 0EEE1BE61E4F6EF400397DE2 /* PIA VPNTests */, + 69B70AAF2ACBF51C0072A09D /* PIA-VPN_E2E_Tests */, ); }; /* End PBXProject section */ @@ -1688,17 +2258,20 @@ 82A1AD2A24B87CCD0003DD02 /* PIACard.xib in Resources */, 82183D9925014FDC0033023F /* CustomNetworkCollectionViewCell.xib in Resources */, DD172AA02254C39300071CFB /* FavoriteServersTile.xib in Resources */, + E501CBFA2AE9806800515006 /* Welcome.strings in Resources */, 0ED66BD020A9918000333B35 /* staging.endpoint in Resources */, DD76292021ECCD510092DF50 /* UsageTileCollectionViewCell.xib in Resources */, + E501CBB72AE97EC800515006 /* Welcome.storyboard in Resources */, DD6DC5C321B6C27F00F9D538 /* pia-spinner.json in Resources */, 0E0715E7201CBB7100D6F666 /* Flags-dev.plist in Resources */, DD1C138A21E60C63004004B3 /* IPTile.xib in Resources */, 82C9F3CF25C43863005039F9 /* ActiveDedicatedIpHeaderViewCell.xib in Resources */, - DD58F4B821AD579A00D043F7 /* GoogleService-Info.plist in Resources */, + E501CBF62AE9806800515006 /* UI.strings in Resources */, 82CAB8F5255C0CD100BB08EF /* MessagesTileCollectionViewCell.xib in Resources */, DD76291421ECBD8B0092DF50 /* SubscriptionTileCollectionViewCell.xib in Resources */, DD51F8BA2372E494009FEED3 /* PIA-RSA-4096.pem in Resources */, DD746958217F070700B7BD73 /* DNS.plist in Resources */, + E501CBFC2AE9806800515006 /* UI.xcassets in Resources */, 0E7EC046209326E30029811E /* Localizable.strings in Resources */, DD76291A21ECBDA50092DF50 /* SubscriptionTile.xib in Resources */, 82183D9725014FDC0033023F /* NetworkCollectionViewCell.xib in Resources */, @@ -1706,6 +2279,7 @@ 82CAB8FE255C115100BB08EF /* MessagesTile.xib in Resources */, DD76292621ECCD650092DF50 /* UsageTile.xib in Resources */, DDFCFA9221E892070081F235 /* RegionTileCollectionViewCell.xib in Resources */, + E501CBF82AE9806800515006 /* Signup.strings in Resources */, DDFCFA9821E8921F0081F235 /* RegionTile.xib in Resources */, 824C531E24C04800003DB740 /* ConnectionTile.xib in Resources */, 0EE220631F4EF307002805AE /* Launch Screen.storyboard in Resources */, @@ -1724,6 +2298,7 @@ 829EB51425359DBB003E74DD /* DedicatedIpRowViewCell.xib in Resources */, 0ED984221FC48C6500542EE6 /* Roboto-Thin.ttf in Resources */, 824C531824C04796003DB740 /* ConnectionTileCollectionViewCell.xib in Resources */, + E501CBB42AE97EBA00515006 /* Signup.storyboard in Resources */, 829EB54D2535BA40003E74DD /* DedicatedIPTitleHeaderViewCell.xib in Resources */, DD9706AE224262E000630220 /* QuickSettingsTileCollectionViewCell.xib in Resources */, DD125DC921E7704F004ECCB6 /* QuickConnectTile.xib in Resources */, @@ -1769,8 +2344,10 @@ 82A1AD2924B87CCD0003DD02 /* PIACard.xib in Resources */, 82183D9A25014FDC0033023F /* NetworkFooterCollectionViewCell.xib in Resources */, 0E7EC045209326E30029811E /* Localizable.strings in Resources */, + E501CBF92AE9806800515006 /* Welcome.strings in Resources */, 0ED9841D1FC48C6000542EE6 /* Roboto-Regular.ttf in Resources */, DD76291F21ECCD510092DF50 /* UsageTileCollectionViewCell.xib in Resources */, + E501CBFB2AE9806800515006 /* UI.xcassets in Resources */, 82C9F3CE25C43863005039F9 /* ActiveDedicatedIpHeaderViewCell.xib in Resources */, DD76292521ECCD650092DF50 /* UsageTile.xib in Resources */, DD172A9C2254C36D00071CFB /* FavoriteServersTileCollectionViewCell.xib in Resources */, @@ -1779,18 +2356,36 @@ 291C6398183EBC210039EC03 /* Images.xcassets in Resources */, 82183D9625014FDC0033023F /* NetworkCollectionViewCell.xib in Resources */, 82183D9825014FDC0033023F /* CustomNetworkCollectionViewCell.xib in Resources */, + E501CBF72AE9806800515006 /* Signup.strings in Resources */, 0E0786DE1EFA7EAE00F77466 /* Components.plist in Resources */, + E501CBB32AE97EBA00515006 /* Signup.storyboard in Resources */, DDFCFA9121E892070081F235 /* RegionTileCollectionViewCell.xib in Resources */, 0ED9841C1FC48C6000542EE6 /* Roboto-Light.ttf in Resources */, 0ED9841E1FC48C6000542EE6 /* Roboto-Thin.ttf in Resources */, 0E7EC0302093265C0029811E /* InfoPlist.strings in Resources */, 291C6393183EBC210039EC03 /* Main.storyboard in Resources */, + E501CBF52AE9806800515006 /* UI.strings in Resources */, 829EB54C2535BA40003E74DD /* DedicatedIPTitleHeaderViewCell.xib in Resources */, 824C531D24C04800003DB740 /* ConnectionTile.xib in Resources */, DD6DC5C221B6C27F00F9D538 /* pia-spinner.json in Resources */, DD746957217F070700B7BD73 /* DNS.plist in Resources */, DD1C139B21E65F90004004B3 /* IPTileCollectionViewCell.xib in Resources */, 829EB5342535AD27003E74DD /* DedicatedIpEmptyHeaderViewCell.xib in Resources */, + E501CBB62AE97EC800515006 /* Welcome.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 69B70AAE2ACBF51C0072A09D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 69B70AAE2ACBF51C0072A09D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1799,6 +2394,8 @@ buildActionMask = 2147483647; files = ( 8269A6DD251CB5E3000B4DBF /* Assets.xcassets in Resources */, + 695BF81D2AC30EFB00D1139C /* Localizable.strings in Resources */, + 698F4F2E2AB97BAD0010B2B0 /* Images.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1838,29 +2435,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if which swiftgen >/dev/null; then\n set -e\n swiftgen\nelse\n echo \"warning: SwiftGen not installed, download it from https://github.com/SwiftGen/SwiftGen\"\nfi\n"; - }; - 11E8771AD2F21EF4B428154B /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-PIA VPN-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; + shellScript = "if which swiftgen >/dev/null; then\n set -e\n #swiftgen\nelse\n echo \"warning: SwiftGen not installed, download it from https://github.com/SwiftGen/SwiftGen\"\nfi\n"; }; 2931563B18513F6500E769A7 /* Download Latest Regions List */ = { isa = PBXShellScriptBuildPhase; @@ -1876,157 +2451,6 @@ shellPath = /bin/bash; shellScript = "# update max once an hour\nset -e\n\nREGIONS_FILE=\"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Regions.json\"\n\nif [[ ! -r \"${REGIONS_FILE}\" || $(find \"${REGIONS_FILE}\" -mmin +60) ]]; then\necho \"downloading regions list to ${REGIONS_FILE}\"\ncurl -sfo \"/tmp/piaios.tmp\" \"https://serverlist.piaservers.net/vpninfo/servers/v6\"\n\nif [ $? -ne 0 ]; then\necho \"failed to fetch regions list from server\"\nexit 1\nfi\n\nhead -n 1 \"/tmp/piaios.tmp\" > \"${REGIONS_FILE}\"\nrm \"/tmp/piaios.tmp\"\nfi\n"; }; - 31FE519987479E33FFCDAB88 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-PIA VPN WG Tunnel-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 5FDBE92B797C696CA4F5D6E3 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-PIA VPN Tunnel-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 6B3D203586AD5EDAB8192C77 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PIA VPNTests/Pods-PIA VPNTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 7103EE1907DBBDBB001EC846 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PIA VPN/Pods-PIA VPN-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - B6830C11847908188577F5A5 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-PIA VPNTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - C26EC034B9AB0A02D7164F82 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-PIA VPN dev-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - DA22F2CE535A37D07F2DE296 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PIA VPN dev/Pods-PIA VPN dev-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - DD58F4B921AE84B300D043F7 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)", - ); - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\"${PODS_ROOT}/Fabric/run\" 970f0999b1ac221604548824b2a49d005754ca32 5606a7ca9a2b622029ba4b67c2adf2e419d60e5460b92564806db96e3141bb72\n"; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -2047,10 +2471,14 @@ 8272C6342657EE4E00D846A8 /* AutomationSettingsViewController.swift in Sources */, 3524670F26B4332E00E3F0AC /* DashboardViewController+ServerSelection.swift in Sources */, 0E9452A01FDB547D00891948 /* ExpirationCell.swift in Sources */, + E59E8FB82AEA7A81009278F5 /* ConfirmVPNPlanViewController.swift in Sources */, + E5F52A202A8A614900828883 /* NetworkMonitor.swift in Sources */, 0EFDC1F01FE4B9E6007C0B9B /* AppConfiguration.swift in Sources */, DD76292321ECCD5C0092DF50 /* UsageTile.swift in Sources */, DDD65314247E66AD00F0A897 /* CoordinatesFinder.swift in Sources */, + E5217F4C2AEAD29F00123442 /* PurchasePlanCell.swift in Sources */, DDD271DF21D616AA00B6D20F /* Server+Favorite.swift in Sources */, + 698F4F312ABA1DA10010B2B0 /* PIAConnectionLiveActivityManager.swift in Sources */, DD125DC621E77046004ECCB6 /* QuickConnectTile.swift in Sources */, 82A1AD2724B86AF60003DD02 /* PIACardsViewController.swift in Sources */, 829EB508253598BD003E74DD /* DedicatedIpViewController.swift in Sources */, @@ -2065,23 +2493,35 @@ DD9706AC224262E000630220 /* QuickSettingsTileCollectionViewCell.swift in Sources */, 82CAB87B255AEA3500BB08EF /* MessagesManager.swift in Sources */, 0E1F318720176A6300FC1000 /* Theme+DarkPalette.swift in Sources */, + E59E8FC62AEA7A81009278F5 /* TermsAndConditionsViewController.swift in Sources */, 8272C6312657D42700D846A8 /* PrivacyFeaturesSettingsViewController.swift in Sources */, 0ECC1E3F1FDB3F2F0039891D /* RegionsViewController.swift in Sources */, + E5F52A192A8A5D5300828883 /* WifiNetworkMonitor.swift in Sources */, + E59E8FB62AEA7A81009278F5 /* GetStartedViewController.swift in Sources */, 8272C62B26551F9B00D846A8 /* SettingPopoverSelectionView.swift in Sources */, 0EB9ED1B1FDA1C4D00D1214D /* SettingsViewController.swift in Sources */, + E59E8FC82AEA7A81009278F5 /* OptionsViewController.swift in Sources */, 0EB966751FDF0D6E0086ABC2 /* ServerProvider+UI.swift in Sources */, 0ECF5C092017EBAD0047596C /* ThemeCode.swift in Sources */, DD76291221ECBD8B0092DF50 /* SubscriptionTileCollectionViewCell.swift in Sources */, + E5217F3A2AEA7B0E00123442 /* Macros+UI.swift in Sources */, DDF7F756240D35BA00A671C7 /* CustomServerSettingsViewController.swift in Sources */, + E59E8FAC2AEA7A81009278F5 /* SignupSuccessViewController.swift in Sources */, 3545E98426AADC7E00B812CC /* ServerSelectionDelegate.swift in Sources */, + E59E8FB42AEA7A81009278F5 /* PIAWelcomeViewController.swift in Sources */, 0E392DA71FE3283C0002160D /* TransientState.swift in Sources */, + E59E8FBE2AEA7A81009278F5 /* SignupFailureViewController.swift in Sources */, 8272C6372657F23400D846A8 /* HelpSettingsViewController.swift in Sources */, DD3B504724B758330002F4B5 /* Collectable.swift in Sources */, 0E3A35361FD9EBDA000B0F99 /* AppDelegate.swift in Sources */, 3545E98326AADC7C00B812CC /* ServerSelectingTileCell.swift in Sources */, + E59E8FC22AEA7A81009278F5 /* ShareDataInformationViewController.swift in Sources */, 824C531624C04796003DB740 /* ConnectionTileCollectionViewCell.swift in Sources */, + E51693D62AFBDB8A0089FB8F /* NavigationBar+Appearence..swift in Sources */, DDC8124D2176185D00CB290C /* SwiftGen+SeguesStoryboards.swift in Sources */, + E5217F552AEAD54600123442 /* WalkthroughPageView.swift in Sources */, DDD271E221D6262100B6D20F /* PropertyStoring.swift in Sources */, + E59E8FB22AEA7A81009278F5 /* LoginViewController.swift in Sources */, DD829EE02449A1EF00E2EE55 /* SiriShortcutsBuilder.swift in Sources */, 0EFB839120209CF200980F69 /* VPNPermissionViewController.swift in Sources */, 0EFDC1D81FE46177007C0B9B /* SensitiveOperation.swift in Sources */, @@ -2097,13 +2537,15 @@ DD829EE32449A4A400E2EE55 /* SiriShortcutsManager.swift in Sources */, DD58F4C021B12CFE00D043F7 /* PIAConnectionButton.swift in Sources */, 827570DE24DABE88008F9800 /* AddCustomNetworksViewController.swift in Sources */, + E5217F732AEB055D00123442 /* Client+Storyboard.swift in Sources */, DD125DD221E7A694004ECCB6 /* ServerButton.swift in Sources */, 8272C62826540B2100D846A8 /* ProtocolSettingsViewController.swift in Sources */, + E59E8FAA2AEA7A81009278F5 /* SignupInternetUnreachableViewController.swift in Sources */, 824C530924C046CB003DB740 /* ConnectionTile.swift in Sources */, 827570D224DAA128008F9800 /* PIAHeaderCollectionViewCell.swift in Sources */, 82F41377264E8AC20098FF4B /* SettingOptions.swift in Sources */, + E59E8FBC2AEA7A81009278F5 /* GDPRViewController.swift in Sources */, 8272C63A2657F54400D846A8 /* DevelopmentSettingsViewController.swift in Sources */, - 0E2215CA2008BA9100F5FB4D /* SwiftGen+Strings.swift in Sources */, DD9329A3237AFD0A0025B6BC /* ShowQuickSettingsViewController.swift in Sources */, DD606ABD21C904BB00E0781D /* PIAHotspotHelper.swift in Sources */, 827570D924DAB6E4008F9800 /* NetworkFooterCollectionViewCell.swift in Sources */, @@ -2113,12 +2555,15 @@ DD125DCD21E772B6004ECCB6 /* QuickConnectTileCollectionViewCell.swift in Sources */, 0E8DCA06204D94E800B086DE /* ContentBlockerViewController.swift in Sources */, DD172A9B2254C36D00071CFB /* FavoriteServersTileCollectionViewCell.swift in Sources */, + E5217F5E2AEAE01400123442 /* NotificationCategory.swift in Sources */, DD76291721ECBD9C0092DF50 /* SubscriptionTile.swift in Sources */, DD51F8C52372E4C8009FEED3 /* PemUtil.swift in Sources */, + E59E8FC42AEA7A81009278F5 /* PurchaseViewController.swift in Sources */, 0EA660091FEC7A9500CB2B0D /* PIATunnelProvider+UI.swift in Sources */, DD3B504A24B75A1E0002F4B5 /* CardFactory.swift in Sources */, DD522D23237D74380072F555 /* BooleanUtil.swift in Sources */, 0E7361EC1FD99A1000706BFF /* MenuViewController.swift in Sources */, + E59E8FAE2AEA7A81009278F5 /* SignupInProgressViewController.swift in Sources */, 0EB966781FDF11B80086ABC2 /* Server+UI.swift in Sources */, DD1C139A21E65F90004004B3 /* IPTileCollectionViewCell.swift in Sources */, 829EB5332535AD27003E74DD /* DedicatedIpEmptyHeaderViewCell.swift in Sources */, @@ -2129,7 +2574,9 @@ 0E2215CD2008C01D00F5FB4D /* SwiftGen+Assets.swift in Sources */, 8272C62E2657B46100D846A8 /* NetworkSettingsViewController.swift in Sources */, DDFCFA9021E892070081F235 /* RegionTileCollectionViewCell.swift in Sources */, + 6924831B2AB045A5002A0407 /* PIAWidgetAttributes.swift in Sources */, DD9706A5224262BF00630220 /* QuickSettingsTile.swift in Sources */, + E5217F672AEAF94C00123442 /* SwiftGen+Assets.swift in Sources */, 82CAB8E9255C0CB000BB08EF /* MessagesTile.swift in Sources */, DD3B504424B7576F0002F4B5 /* Card.swift in Sources */, 82183D7C2500FD460033023F /* String+Substrings.swift in Sources */, @@ -2138,9 +2585,12 @@ 829EB51225359DBB003E74DD /* DedicatedIpRowViewCell.swift in Sources */, DDFCFA9521E892130081F235 /* RegionTile.swift in Sources */, 0EFDC1E71FE4ABAA007C0B9B /* Notification+App.swift in Sources */, + E5F52A1C2A8A5E1E00828883 /* IPv4Address.swift in Sources */, 827570E224DAC2C6008F9800 /* CustomNetworkCollectionViewCell.swift in Sources */, DD918577246BFA7F006B3A2B /* RatingManager.swift in Sources */, + E5217F492AEAD28000123442 /* UIViewLoading.swift in Sources */, 82C0071425231F2800F21AF2 /* String+VPNType.swift in Sources */, + E5217F412AEAC7A900123442 /* Theme+LightPalette.swift in Sources */, DD1C138721E60BAE004004B3 /* IPTile.swift in Sources */, 0E9452971FDB4C5800891948 /* AboutComponentCell.swift in Sources */, 3524670C26B432BC00E3F0AC /* TrustedNetworkHelper.swift in Sources */, @@ -2148,14 +2598,25 @@ 0EFDC1E11FE4A450007C0B9B /* AppPreferences.swift in Sources */, 0E441E272055AEDF007528D5 /* ThemeStrategy+App.swift in Sources */, DDC8125021761B0B00CB290C /* SwiftGen+ScenesStoryboards.swift in Sources */, + 69B70ABF2ACC2CFE0072A09D /* AccessibilityId.swift in Sources */, + 7ECBB8DE27BA5FCE00C0C774 /* UserSurveyManager.swift in Sources */, 0E492C681FE60907007F23DF /* Flags.swift in Sources */, DD172A972254C35000071CFB /* FavoriteServersTile.swift in Sources */, 0EE14D191FF15812008D9AC2 /* ModalNavigationSegue.swift in Sources */, + E59E8FBA2AEA7A81009278F5 /* RestoreSignupViewController.swift in Sources */, + E5217F432AEAC7A900123442 /* Theme.swift in Sources */, 826BE8EF253861BE002339F3 /* DedicatedRegionCell.swift in Sources */, + E51693D22AFADCC20089FB8F /* SwiftGen+Strings.swift in Sources */, + E51693D92AFBE5680089FB8F /* CAGradientLayer+Image.swift in Sources */, 82B7374C26527E330097FFF6 /* GeneralSettingsViewController.swift in Sources */, + E59E8F952AEA7A29009278F5 /* ActivityButton.swift in Sources */, + E59E8FC02AEA7A81009278F5 /* WelcomePageViewController.swift in Sources */, 82CAB8F3255C0CD100BB08EF /* MessagesTileCollectionViewCell.swift in Sources */, + E5217F462AEACE0200123442 /* NavigationLogoView.swift in Sources */, + E59E8FB02AEA7A81009278F5 /* MagicLinkLoginViewController.swift in Sources */, 0E3A352D1FD9CDC5000B0F99 /* Theme+App.swift in Sources */, DD07AACD242CBFF3000EE1A3 /* AddEmailToAccountViewController.swift in Sources */, + E5217F702AEB042800123442 /* ClientError+Localization.swift in Sources */, DD1C139F21E6623D004004B3 /* XIBSetup.swift in Sources */, DDB6B95421C95CD400DE8C5F /* EnumsBuilder.swift in Sources */, 0E9AEA6320683FDF00B6E59A /* AboutComponent.swift in Sources */, @@ -2176,7 +2637,6 @@ DD606AC821C9344100E0781D /* AppTests.swift in Sources */, 82A1AD2324B7C0020003DD02 /* PIACardTests.swift in Sources */, 8221922B24CECFE700C24F1C /* NMTTests.swift in Sources */, - 82CAB8DA255BEC7000BB08EF /* PIACommandTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2206,56 +2666,80 @@ 0EFDC1EF1FE4B9E6007C0B9B /* AppConfiguration.swift in Sources */, 0E9452A21FDB568700891948 /* MenuItemCell.swift in Sources */, 829EB51125359DBB003E74DD /* DedicatedIpRowViewCell.swift in Sources */, + E59E8FBF2AEA7A81009278F5 /* WelcomePageViewController.swift in Sources */, 0EFDC1DA1FE4640C007C0B9B /* DNSResolver.swift in Sources */, 0E9452991FDB4DF500891948 /* GradientView.swift in Sources */, 0E7361E81FD98C3400706BFF /* AccountViewController.swift in Sources */, DD1C13A421E6743F004004B3 /* TileFlowLayout.swift in Sources */, DD76291D21ECCD510092DF50 /* UsageTileCollectionViewCell.swift in Sources */, + E59E8FC52AEA7A81009278F5 /* TermsAndConditionsViewController.swift in Sources */, + E59E8FB52AEA7A81009278F5 /* GetStartedViewController.swift in Sources */, + E59E8F972AEA7A5A009278F5 /* AutolayoutViewController.swift in Sources */, + E5217F722AEB055D00123442 /* Client+Storyboard.swift in Sources */, DD9706AB224262E000630220 /* QuickSettingsTileCollectionViewCell.swift in Sources */, 0EE14D151FF15626008D9AC2 /* UINavigationController+StatusBar.swift in Sources */, 0E1F318620176A5F00FC1000 /* Theme+DarkPalette.swift in Sources */, + E5217F3C2AEA886000123442 /* BorderedTextField.swift in Sources */, 0ECC1E3E1FDB3F2F0039891D /* RegionsViewController.swift in Sources */, 8272C6302657D42700D846A8 /* PrivacyFeaturesSettingsViewController.swift in Sources */, + E5217F482AEAD28000123442 /* UIViewLoading.swift in Sources */, 0EB9ED1A1FDA1C4D00D1214D /* SettingsViewController.swift in Sources */, 0EB966741FDF0D6E0086ABC2 /* ServerProvider+UI.swift in Sources */, DD76291121ECBD8B0092DF50 /* SubscriptionTileCollectionViewCell.swift in Sources */, 8272C6332657EE4E00D846A8 /* AutomationSettingsViewController.swift in Sources */, + E59E8FBB2AEA7A81009278F5 /* GDPRViewController.swift in Sources */, DDF7F755240D35BA00A671C7 /* CustomServerSettingsViewController.swift in Sources */, 0ECF5C082017EBAD0047596C /* ThemeCode.swift in Sources */, 3545E98026AAD60C00B812CC /* ServerSelectionDelegate.swift in Sources */, + E5217F402AEAC7A900123442 /* Theme+LightPalette.swift in Sources */, + E5217F392AEA7B0E00123442 /* Macros+UI.swift in Sources */, + E59E8FA92AEA7A81009278F5 /* SignupInternetUnreachableViewController.swift in Sources */, 0E392DA61FE3283C0002160D /* TransientState.swift in Sources */, + 6924831A2AB045A5002A0407 /* PIAWidgetAttributes.swift in Sources */, 82F41376264E8AC20098FF4B /* SettingOptions.swift in Sources */, 824C531524C04796003DB740 /* ConnectionTileCollectionViewCell.swift in Sources */, 0E3A35351FD9EBDA000B0F99 /* AppDelegate.swift in Sources */, DD3B504924B75A1E0002F4B5 /* CardFactory.swift in Sources */, DD829EDF2449A1EF00E2EE55 /* SiriShortcutsBuilder.swift in Sources */, DDC8124C2176185000CB290C /* SwiftGen+SeguesStoryboards.swift in Sources */, + E51693D82AFBE5680089FB8F /* CAGradientLayer+Image.swift in Sources */, DDD271E121D6262100B6D20F /* PropertyStoring.swift in Sources */, 82A1AD2F24B87CF20003DD02 /* PIACard.swift in Sources */, 8272C6392657F54400D846A8 /* DevelopmentSettingsViewController.swift in Sources */, 0EFB839020209CF200980F69 /* VPNPermissionViewController.swift in Sources */, + 7ECBB8DD27B6C4F500C0C774 /* UserSurveyManager.swift in Sources */, 821674F12678A1BE0028E4FD /* SettingsDelegate.swift in Sources */, 0EFDC1D71FE46177007C0B9B /* SensitiveOperation.swift in Sources */, + E59E8FAB2AEA7A81009278F5 /* SignupSuccessViewController.swift in Sources */, 82C0071325231F2800F21AF2 /* String+VPNType.swift in Sources */, 826BE8EE253861BE002339F3 /* DedicatedRegionCell.swift in Sources */, 0E3A35281FD9A960000B0F99 /* DashboardViewController.swift in Sources */, DDB6B95021C94E2E00DE8C5F /* TrustedNetworksViewController.swift in Sources */, 82C9F3CC25C43863005039F9 /* ActiveDedicatedIpHeaderViewCell.swift in Sources */, + E59E8FAF2AEA7A81009278F5 /* MagicLinkLoginViewController.swift in Sources */, 8276DFE62608B63800BB7B40 /* ShowConnectionStatsViewController.swift in Sources */, 827570D424DAA317008F9800 /* NetworkRuleOptionView.swift in Sources */, 0E9452A51FDB578400891948 /* RegionCell.swift in Sources */, DD829EE22449A4A400E2EE55 /* SiriShortcutsManager.swift in Sources */, + E51693D12AFADCC20089FB8F /* SwiftGen+Strings.swift in Sources */, 82BAACFA25B09C9200B3C733 /* PIAWidget.intentdefinition in Sources */, 0EFDC1EC1FE4B9DC007C0B9B /* AppConstants.swift in Sources */, 827570DD24DABE88008F9800 /* AddCustomNetworksViewController.swift in Sources */, 8272C62A26551F9B00D846A8 /* SettingPopoverSelectionView.swift in Sources */, + E59E8FB72AEA7A81009278F5 /* ConfirmVPNPlanViewController.swift in Sources */, + E59E8FC12AEA7A81009278F5 /* ShareDataInformationViewController.swift in Sources */, DD58F4BF21B12CFE00D043F7 /* PIAConnectionButton.swift in Sources */, 824C530824C046CB003DB740 /* ConnectionTile.swift in Sources */, 827570D124DAA128008F9800 /* PIAHeaderCollectionViewCell.swift in Sources */, + E51693C62AFAD3550089FB8F /* UIDevice+WIFI.swift in Sources */, DD125DD121E7A694004ECCB6 /* ServerButton.swift in Sources */, DD9329A2237AFD0A0025B6BC /* ShowQuickSettingsViewController.swift in Sources */, + 69B70ABE2ACC2CFE0072A09D /* AccessibilityId.swift in Sources */, 0E2215C920084CD700F5FB4D /* SwiftGen+Strings.swift in Sources */, 827570D824DAB6E4008F9800 /* NetworkFooterCollectionViewCell.swift in Sources */, + E5217F6F2AEB042800123442 /* ClientError+Localization.swift in Sources */, + E5F52A1F2A8A614900828883 /* NetworkMonitor.swift in Sources */, + E59E8FB12AEA7A81009278F5 /* LoginViewController.swift in Sources */, DD3B504324B7576F0002F4B5 /* Card.swift in Sources */, 82CAB8F2255C0CD100BB08EF /* MessagesTileCollectionViewCell.swift in Sources */, DD606ABC21C904BB00E0781D /* PIAHotspotHelper.swift in Sources */, @@ -2270,6 +2754,7 @@ 0EA660081FEC7A9500CB2B0D /* PIATunnelProvider+UI.swift in Sources */, 0E7361EB1FD99A1000706BFF /* MenuViewController.swift in Sources */, DD1C139921E65F90004004B3 /* IPTileCollectionViewCell.swift in Sources */, + E5F52A182A8A5D5300828883 /* WifiNetworkMonitor.swift in Sources */, 827570CF24DAA128008F9800 /* NetworkCollectionViewCell.swift in Sources */, 0EB966771FDF11B80086ABC2 /* Server+UI.swift in Sources */, DD052AC32419003300AD3A24 /* ProtocolTableViewCell.swift in Sources */, @@ -2283,50 +2768,112 @@ 0E7361A01FD86F8300706BFF /* AccountObserver.swift in Sources */, 0EFDC1E61FE4ABAA007C0B9B /* Notification+App.swift in Sources */, 827570E124DAC2C6008F9800 /* CustomNetworkCollectionViewCell.swift in Sources */, + E5217F452AEACE0200123442 /* NavigationLogoView.swift in Sources */, 3524670E26B432ED00E3F0AC /* DashboardViewController+ServerSelection.swift in Sources */, + E59E8FC72AEA7A81009278F5 /* OptionsViewController.swift in Sources */, DD918576246BFA7F006B3A2B /* RatingManager.swift in Sources */, DD1C138621E60BAE004004B3 /* IPTile.swift in Sources */, 0E9452961FDB4C5800891948 /* AboutComponentCell.swift in Sources */, 0E53A83B1FE5A156000C2A18 /* AccountProvider+Refresh.swift in Sources */, 82B7374B26527E330097FFF6 /* GeneralSettingsViewController.swift in Sources */, 0EFDC1E01FE4A450007C0B9B /* AppPreferences.swift in Sources */, + E51693D52AFBDB8A0089FB8F /* NavigationBar+Appearence..swift in Sources */, 3524670B26B431B800E3F0AC /* TrustedNetworkHelper.swift in Sources */, 829EB54A2535BA40003E74DD /* DedicatedIPTitleHeaderViewCell.swift in Sources */, 82B7374F265280180097FFF6 /* PIABaseSettingsViewController.swift in Sources */, DDC8124F21761B0B00CB290C /* SwiftGen+ScenesStoryboards.swift in Sources */, 0E492C671FE60907007F23DF /* Flags.swift in Sources */, 0EE14D181FF15812008D9AC2 /* ModalNavigationSegue.swift in Sources */, + E5217F5D2AEAE01400123442 /* NotificationCategory.swift in Sources */, + E5217F422AEAC7A900123442 /* Theme.swift in Sources */, DD172A962254C35000071CFB /* FavoriteServersTile.swift in Sources */, + E59E8FB32AEA7A81009278F5 /* PIAWelcomeViewController.swift in Sources */, 0E3A352C1FD9CDC5000B0F99 /* Theme+App.swift in Sources */, 82CAB8E8255C0CB000BB08EF /* MessagesTile.swift in Sources */, 8272C6362657F23400D846A8 /* HelpSettingsViewController.swift in Sources */, DD1C139E21E6623D004004B3 /* XIBSetup.swift in Sources */, DD07AACC242CBFF2000EE1A3 /* AddEmailToAccountViewController.swift in Sources */, 8272C62726540B2100D846A8 /* ProtocolSettingsViewController.swift in Sources */, + E59E8F942AEA7A29009278F5 /* ActivityButton.swift in Sources */, 82CAB8B0255B050000BB08EF /* MessagesCommands.swift in Sources */, DDE432DF2498EADB0095B197 /* Array+Group.swift in Sources */, + 698F4F302ABA1DA10010B2B0 /* PIAConnectionLiveActivityManager.swift in Sources */, DDB6B95321C95CD400DE8C5F /* EnumsBuilder.swift in Sources */, 3545E98226AADB2B00B812CC /* ServerSelectingTileCell.swift in Sources */, 829EB5322535AD27003E74DD /* DedicatedIpEmptyHeaderViewCell.swift in Sources */, 829EB51C2535A8FF003E74DD /* CollectionViewAutoSizeUtils.swift in Sources */, 0E9AEA6220683FDF00B6E59A /* AboutComponent.swift in Sources */, + E59E8FB92AEA7A81009278F5 /* RestoreSignupViewController.swift in Sources */, + E59E8FAD2AEA7A81009278F5 /* SignupInProgressViewController.swift in Sources */, + E5217F4B2AEAD29F00123442 /* PurchasePlanCell.swift in Sources */, DD4E84572243BD1200929B39 /* DashboardCollectionViewUtil.swift in Sources */, 829EB507253598BD003E74DD /* DedicatedIpViewController.swift in Sources */, DD74695A217F07AC00B7BD73 /* DNSList.swift in Sources */, + E59E8FBD2AEA7A81009278F5 /* SignupFailureViewController.swift in Sources */, + E5F52A1B2A8A5E1E00828883 /* IPv4Address.swift in Sources */, + E5217F542AEAD54600123442 /* WalkthroughPageView.swift in Sources */, 0E9452AE1FDB5F7A00891948 /* PIAPageControl.swift in Sources */, DDD271F021D6718F00B6D20F /* RegionFilter.swift in Sources */, + E5217F662AEAF94C00123442 /* SwiftGen+Assets.swift in Sources */, 82CAB87A255AEA3500BB08EF /* MessagesManager.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + 69B70AAC2ACBF51C0072A09D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 35EDD6442AE7B480007B9ACB /* Common.swift in Sources */, + 35EDD63E2AE76A3B007B9ACB /* WaitHelper.swift in Sources */, + 35EDD6282ADE5D31007B9ACB /* BaseTest.swift in Sources */, + 35EDD65E2B048C68007B9ACB /* QuickSettingsScreen.swift in Sources */, + 35EDD65A2B035B51007B9ACB /* SideMenuScreen.swift in Sources */, + 35EDD6352ADE7424007B9ACB /* VPNPermissionScreen.swift in Sources */, + 699F23B32AFBA66000EBC5E6 /* HelpSettingsScreen.swift in Sources */, + 69B70ABC2ACBF8300072A09D /* CredentialsUtil.swift in Sources */, + 35EDD6372ADE761A007B9ACB /* HomeScreen.swift in Sources */, + 35EDD63B2AE62D15007B9ACB /* ElementHelper.swift in Sources */, + 69C587FD2AD00C6300B95EF9 /* PIAExampleWithAuthenticatedAppTest.swift in Sources */, + 699F23B22AFBA66000EBC5E6 /* SettingsScreen.swift in Sources */, + 35EDD6422AE7A83D007B9ACB /* WelcomeScreen.swift in Sources */, + 699F23B92AFBAC0B00EBC5E6 /* UpdateSettingsTests.swift in Sources */, + 699F23B42AFBA66000EBC5E6 /* AutomationSettingsScreen.swift in Sources */, + 35EDD62A2ADE5F08007B9ACB /* SignInTests.swift in Sources */, + 69B70AB52ACBF51C0072A09D /* LoginScreen.swift in Sources */, + 35EDD65C2B047839007B9ACB /* QuickSettingsTests.swift in Sources */, + 35EDD6332ADE7281007B9ACB /* OnboardingTests.swift in Sources */, + 699F23B52AFBA66000EBC5E6 /* ProtocolsSettingsScreen.swift in Sources */, + 69B70AC02ACC2CFE0072A09D /* AccessibilityId.swift in Sources */, + 699F23B62AFBA66000EBC5E6 /* GeneralSettingsScreen.swift in Sources */, + 699F23B72AFBA66000EBC5E6 /* PrivacySettingsScreen.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 8269A6D1251CB5E0000B4DBF /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8269A6FE251CBB36000B4DBF /* WidgetContent.swift in Sources */, - 822F97B4251DD53100644EF2 /* WidgetUtils.swift in Sources */, + E51693D32AFAE3670089FB8F /* SwiftGen+Strings.swift in Sources */, + 8269A6FE251CBB36000B4DBF /* WidgetInformation.swift in Sources */, + 695BF81F2AC410E000D1139C /* SwiftGen+Strings.swift in Sources */, + 698F4F2D2AB978BF0010B2B0 /* PIACircleImageView.swift in Sources */, + 822F97B4251DD53100644EF2 /* WidgetUserDefaultsDatasource.swift in Sources */, 8269A6DA251CB5E0000B4DBF /* PIAWidget.swift in Sources */, + 692483222AB05F37002A0407 /* PIACircleIcon.swift in Sources */, + AAE878A928E4765F00557F26 /* PIAIconView.swift in Sources */, + 6924831E2AB04FFD002A0407 /* PIAWidgetBundle.swift in Sources */, + AAE8789F28E4696300557F26 /* PIAWidgetProvider.swift in Sources */, + AAE878A128E46C1600557F26 /* PIAWidgetPreview.swift in Sources */, + 692483262AB05F85002A0407 /* PIAConnectionActivityWidget.swift in Sources */, + AAE878A528E4723B00557F26 /* PIACircleVpnButton.swift in Sources */, 82BAACFB25B09C9200B3C733 /* PIAWidget.intentdefinition in Sources */, + AAE8789C28E4679500557F26 /* WidgetPersistenceDatasource.swift in Sources */, + AAE878A328E46D2B00557F26 /* PIAWidgetView.swift in Sources */, + 6924831C2AB045A5002A0407 /* PIAWidgetAttributes.swift in Sources */, + 698F4F322ABA1DA10010B2B0 /* PIAConnectionLiveActivityManager.swift in Sources */, + 692483202AB05F18002A0407 /* PIAConnectionView.swift in Sources */, + AAE878A728E473A400557F26 /* PIAWidgetVpnDetailsView.swift in Sources */, + AA52C59F28E5ECD400D025AF /* PIAWidgetVpnDetaislRow.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2371,11 +2918,26 @@ target = 0EFB606F203D7A2C0095398C /* PIA VPN AdBlocker */; targetProxy = 0EFB607E203D893E0095398C /* PBXContainerItemProxy */; }; + 69CB24A32B051CED00D83A52 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 291C637B183EBC210039EC03 /* PIA VPN */; + targetProxy = 69CB24A22B051CED00D83A52 /* PBXContainerItemProxy */; + }; 8269A6E2251CB5E3000B4DBF /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 8269A6D4251CB5E0000B4DBF /* PIAWidgetExtension */; targetProxy = 8269A6E1251CB5E3000B4DBF /* PBXContainerItemProxy */; }; + AABF827A28AE336000CDAC64 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DDC8F5EB23EC106F005D19C6 /* PIA VPN WG Tunnel */; + targetProxy = AABF827928AE336000CDAC64 /* PBXContainerItemProxy */; + }; + AABF827C28AE336F00CDAC64 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8269A6D4251CB5E0000B4DBF /* PIAWidgetExtension */; + targetProxy = AABF827B28AE336F00CDAC64 /* PBXContainerItemProxy */; + }; DDC8F5F323EC1070005D19C6 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DDC8F5EB23EC106F005D19C6 /* PIA VPN WG Tunnel */; @@ -2450,12 +3012,86 @@ name = PIAWidget.intentdefinition; sourceTree = ""; }; + E501CBBA2AE9806800515006 /* UI.strings */ = { + isa = PBXVariantGroup; + children = ( + E501CBBB2AE9806800515006 /* de */, + E501CBBC2AE9806800515006 /* ar */, + E501CBBD2AE9806800515006 /* zh-Hans */, + E501CBBE2AE9806800515006 /* ja */, + E501CBBF2AE9806800515006 /* en */, + E501CBC02AE9806800515006 /* nb */, + E501CBC12AE9806800515006 /* da */, + E501CBC22AE9806800515006 /* it */, + E501CBC32AE9806800515006 /* ko */, + E501CBC42AE9806800515006 /* zh-Hant */, + E501CBC52AE9806800515006 /* tr */, + E501CBC62AE9806800515006 /* pl */, + E501CBC72AE9806800515006 /* pt-BR */, + E501CBC82AE9806800515006 /* es-MX */, + E501CBC92AE9806800515006 /* ru */, + E501CBCA2AE9806800515006 /* fr */, + E501CBCB2AE9806800515006 /* nl */, + E501CBCC2AE9806800515006 /* th */, + ); + name = UI.strings; + sourceTree = ""; + }; + E501CBCE2AE9806800515006 /* Signup.strings */ = { + isa = PBXVariantGroup; + children = ( + E501CBCF2AE9806800515006 /* de */, + E501CBD22AE9806800515006 /* ar */, + E501CBD42AE9806800515006 /* zh-Hans */, + E501CBD62AE9806800515006 /* ja */, + E501CBD82AE9806800515006 /* en */, + E501CBDA2AE9806800515006 /* nb */, + E501CBDD2AE9806800515006 /* da */, + E501CBDF2AE9806800515006 /* it */, + E501CBE12AE9806800515006 /* ko */, + E501CBE32AE9806800515006 /* zh-Hant */, + E501CBE52AE9806800515006 /* tr */, + E501CBE72AE9806800515006 /* pl */, + E501CBE92AE9806800515006 /* pt-BR */, + E501CBEB2AE9806800515006 /* es-MX */, + E501CBED2AE9806800515006 /* ru */, + E501CBEF2AE9806800515006 /* fr */, + E501CBF12AE9806800515006 /* nl */, + E501CBF32AE9806800515006 /* th */, + ); + name = Signup.strings; + sourceTree = ""; + }; + E501CBD02AE9806800515006 /* Welcome.strings */ = { + isa = PBXVariantGroup; + children = ( + E501CBD12AE9806800515006 /* de */, + E501CBD32AE9806800515006 /* ar */, + E501CBD52AE9806800515006 /* zh-Hans */, + E501CBD72AE9806800515006 /* ja */, + E501CBD92AE9806800515006 /* en */, + E501CBDB2AE9806800515006 /* nb */, + E501CBDE2AE9806800515006 /* da */, + E501CBE02AE9806800515006 /* it */, + E501CBE22AE9806800515006 /* ko */, + E501CBE42AE9806800515006 /* zh-Hant */, + E501CBE62AE9806800515006 /* tr */, + E501CBE82AE9806800515006 /* pl */, + E501CBEA2AE9806800515006 /* pt-BR */, + E501CBEC2AE9806800515006 /* es-MX */, + E501CBEE2AE9806800515006 /* ru */, + E501CBF02AE9806800515006 /* fr */, + E501CBF22AE9806800515006 /* nl */, + E501CBF42AE9806800515006 /* th */, + ); + name = Welcome.strings; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 0E67FC2C1E3F802D00EF9929 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E65358880CC5204F785ADE10 /* Pods-PIA VPN Tunnel.debug.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_MODULES = YES; @@ -2463,14 +3099,18 @@ CODE_SIGN_ENTITLEMENTS = "PIA VPN Tunnel/PIA VPN Tunnel.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 19748; + CURRENT_PROJECT_VERSION = 20042; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 5357M5NW9W; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "PIA VPN Tunnel/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.1; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 3.14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 3.23.3; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.PIA-VPN.Tunnel"; PRODUCT_NAME = "PIA VPN Tunnel"; @@ -2485,7 +3125,6 @@ }; 0E67FC2D1E3F802D00EF9929 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = AC26C61F8D1F24341AD67A4A /* Pods-PIA VPN Tunnel.release.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_MODULES = YES; @@ -2494,19 +3133,25 @@ CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 19748; + CURRENT_PROJECT_VERSION = 20042; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 5357M5NW9W; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5357M5NW9W; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "PIA VPN Tunnel/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.1; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 3.14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 3.23.3; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.PIA-VPN.Tunnel"; PRODUCT_NAME = "PIA VPN Tunnel"; PROVISIONING_PROFILE = "b5b9e54d-7aba-4fc6-9320-adbce64c544a"; PROVISIONING_PROFILE_SPECIFIER = "match AdHoc com.privateinternetaccess.ios.PIA-VPN.Tunnel"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.privateinternetaccess.ios.PIA-VPN.Tunnel"; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -2514,7 +3159,6 @@ }; 0EE220781F4EF307002805AE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7F6FF659836C1192332662A8 /* Pods-PIA VPN dev.debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; ARCHS = "$(ARCHS_STANDARD)"; @@ -2523,9 +3167,9 @@ CODE_SIGN_ENTITLEMENTS = "PIA VPN/PIA VPN.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 19748; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 5357M5NW9W; - ENABLE_BITCODE = YES; + ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -2535,12 +3179,15 @@ ); INFOPLIST_FILE = "PIA VPN/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.1; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)", ); - MARKETING_VERSION = 3.14.0; + MARKETING_VERSION = 3.23.4; PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.PIA-VPN"; PRODUCT_MODULE_NAME = PIA_VPN_dev; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2556,7 +3203,6 @@ }; 0EE220791F4EF307002805AE /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EFF4BBB886BD153CAD50F8E2 /* Pods-PIA VPN dev.release.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; ARCHS = "$(ARCHS_STANDARD)"; @@ -2565,9 +3211,9 @@ CODE_SIGN_ENTITLEMENTS = "PIA VPN/PIA VPN.entitlements"; CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 19748; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 5357M5NW9W; - ENABLE_BITCODE = YES; + ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -2577,12 +3223,15 @@ ); INFOPLIST_FILE = "PIA VPN/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.1; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)", ); - MARKETING_VERSION = 3.14.0; + MARKETING_VERSION = 3.23.4; PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.PIA-VPN"; PRODUCT_MODULE_NAME = PIA_VPN_dev; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2597,7 +3246,6 @@ }; 0EEE1BEE1E4F6EF400397DE2 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 59EC919445EA680B691ACC88 /* Pods-PIA VPNTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NONNULL = YES; @@ -2612,7 +3260,11 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "PIA VPNTests/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.1; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.PIA-VPNTests"; "PRODUCT_BUNDLE_IDENTIFIER[sdk=macosx*]" = ""; @@ -2629,14 +3281,12 @@ }; 0EEE1BEF1E4F6EF400397DE2 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 678A887CFC02122F4FB83216 /* Pods-PIA VPNTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_MODULES = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -2645,13 +3295,16 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "PIA VPNTests/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.1; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.PIA-VPNTests"; "PRODUCT_BUNDLE_IDENTIFIER[sdk=macosx*]" = ""; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; SWIFT_OBJC_INTERFACE_HEADER_NAME = "$(SWIFT_MODULE_NAME)-Swift.h"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PIA VPN.app/PIA VPN"; @@ -2668,15 +3321,19 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 19748; + CURRENT_PROJECT_VERSION = 20042; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 5357M5NW9W; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "PIA VPN AdBlocker/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 3.14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 3.23.3; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.PIA-VPN.AdBlocker"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2701,20 +3358,26 @@ CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 19748; + CURRENT_PROJECT_VERSION = 20042; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 5357M5NW9W; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5357M5NW9W; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "PIA VPN AdBlocker/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 3.14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 3.23.3; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.PIA-VPN.AdBlocker"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = "5aba703f-4bee-46e6-a5e4-42b785d1db55"; PROVISIONING_PROFILE_SPECIFIER = "match AdHoc com.privateinternetaccess.ios.PIA-VPN.AdBlocker"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.privateinternetaccess.ios.PIA-VPN.AdBlocker"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -2823,7 +3486,8 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 11.0; SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; VALIDATE_PRODUCT = YES; }; @@ -2831,7 +3495,6 @@ }; 291C63AF183EBC220039EC03 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F489C6FC39A7285DDE2A26F7 /* Pods-PIA VPN.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ARCHS = "$(ARCHS_STANDARD)"; @@ -2840,9 +3503,9 @@ CODE_SIGN_ENTITLEMENTS = "PIA VPN/PIA VPN.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 19748; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 5357M5NW9W; - ENABLE_BITCODE = YES; + ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "\"${PODS_ROOT}/PIAAccount/frameworks/iPhone\"", @@ -2850,12 +3513,15 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; INFOPLIST_FILE = "PIA VPN/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.1; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)", ); - MARKETING_VERSION = 3.14.0; + MARKETING_VERSION = 3.23.4; PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match Development com.privateinternetaccess.ios.PIA-VPN"; @@ -2868,18 +3534,19 @@ }; 291C63B0183EBC220039EC03 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0BE4A5FC9BACD5CAB3D6CEF0 /* Pods-PIA VPN.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ARCHS = "$(ARCHS_STANDARD)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = "PIA VPN/PIA VPN.entitlements"; - CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 19748; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 5357M5NW9W; - ENABLE_BITCODE = YES; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5357M5NW9W; + ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "\"${PODS_ROOT}/PIAAccount/frameworks/iPhone\"", @@ -2887,21 +3554,90 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; INFOPLIST_FILE = "PIA VPN/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.1; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)", ); - MARKETING_VERSION = 3.14.0; + MARKETING_VERSION = 3.23.4; PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match AdHoc com.privateinternetaccess.ios.PIA-VPN"; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.privateinternetaccess.ios.PIA-VPN"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.privateinternetaccess.ios.PIA-VPN"; SWIFT_OBJC_BRIDGING_HEADER = ""; TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; name = Release; }; + 69B70AB82ACBF51C0072A09D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 5357M5NW9W; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.PIA-VPN.e2e-Tests.PIA-VPN-E2E-Tests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = "420cc0bf-ef09-4d4c-b1b3-9d7cffd4d201"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "PIA VPN"; + }; + name = Debug; + }; + 69B70AB92ACBF51C0072A09D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 5357M5NW9W; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.PIA-VPN.e2e-Tests.PIA-VPN-E2E-Tests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = "420cc0bf-ef09-4d4c-b1b3-9d7cffd4d201"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "PIA VPN"; + }; + name = Release; + }; 8269A6E5251CB5E3000B4DBF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2917,15 +3653,19 @@ CODE_SIGN_ENTITLEMENTS = PIAWidgetExtension.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 19748; + CURRENT_PROJECT_VERSION = 20042; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 5357M5NW9W; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = PIAWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 3.14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 3.23.3; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.PIA-VPN.PIAWidget"; @@ -2955,20 +3695,26 @@ CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 19748; + CURRENT_PROJECT_VERSION = 20042; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 5357M5NW9W; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5357M5NW9W; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = PIAWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 3.14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 3.23.3; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.PIA-VPN.PIAWidget"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match AdHoc com.privateinternetaccess.ios.PIA-VPN.PIAWidget"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.privateinternetaccess.ios.PIA-VPN.PIAWidget"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -2977,7 +3723,6 @@ }; DDC8F5F523EC1070005D19C6 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A6454C66DD80FE480E48BFA8 /* Pods-PIA VPN WG Tunnel.debug.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -2988,15 +3733,19 @@ CODE_SIGN_ENTITLEMENTS = "PIA VPN WG Tunnel/PIA_VPN_WG_Tunnel.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 19748; + CURRENT_PROJECT_VERSION = 20042; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 5357M5NW9W; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "PIA VPN WG Tunnel/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 3.14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 3.23.3; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.PIA-VPN.WG-Tunnel"; @@ -3012,7 +3761,6 @@ }; DDC8F5F623EC1070005D19C6 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B5E30A2B8E23D816328C690E /* Pods-PIA VPN WG Tunnel.release.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3024,20 +3772,26 @@ CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 19748; + CURRENT_PROJECT_VERSION = 20042; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 5357M5NW9W; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5357M5NW9W; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "PIA VPN WG Tunnel/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 3.14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 3.23.3; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.privateinternetaccess.ios.PIA-VPN.WG-Tunnel"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match AdHoc com.privateinternetaccess.ios.PIA-VPN.WG-Tunnel"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.privateinternetaccess.ios.PIA-VPN.WG-Tunnel"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -3101,6 +3855,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 69B70ABA2ACBF51C0072A09D /* Build configuration list for PBXNativeTarget "PIA-VPN_E2E_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 69B70AB82ACBF51C0072A09D /* Debug */, + 69B70AB92ACBF51C0072A09D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 8269A6E4251CB5E3000B4DBF /* Build configuration list for PBXNativeTarget "PIAWidgetExtension" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -3120,6 +3883,215 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 35950B2F2ADD2877006F3CD9 /* XCRemoteSwiftPackageReference "Quick" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Quick/Quick"; + requirement = { + kind = exactVersion; + version = 7.3.0; + }; + }; + 35950B322ADD2EE5006F3CD9 /* XCRemoteSwiftPackageReference "Nimble" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Quick/Nimble"; + requirement = { + kind = exactVersion; + version = 13.0.0; + }; + }; + 697C59AA2AFD0770008B6212 /* XCRemoteSwiftPackageReference "mobile-ios-library" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "git@github.com:pia-foss/mobile-ios-library.git"; + requirement = { + kind = exactVersion; + version = 7.3.0; + }; + }; + 35950B322ADD2EE5006F3CD9 /* XCRemoteSwiftPackageReference "Nimble" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Quick/Nimble"; + requirement = { + kind = exactVersion; + version = 13.0.0; + }; + }; + AA36CDB928A6622A00180A33 /* XCRemoteSwiftPackageReference "tweetnacl-swiftwrap" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/bitmark-inc/tweetnacl-swiftwrap.git"; + requirement = { + kind = exactVersion; + version = 1.1.0; + }; + }; + AA36CDC228A6711300180A33 /* XCRemoteSwiftPackageReference "Popover" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/sarathsarah/Popover.git"; + requirement = { + branch = master; + kind = branch; + }; + }; + AA36CDC728A6733500180A33 /* XCRemoteSwiftPackageReference "DZNEmptyDataSet" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/dzenbot/DZNEmptyDataSet.git"; + requirement = { + branch = master; + kind = branch; + }; + }; + AA36CDCA28A673C900180A33 /* XCRemoteSwiftPackageReference "GradientProgressBar" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/fxm90/GradientProgressBar.git"; + requirement = { + kind = exactVersion; + version = 2.0.3; + }; + }; + AA36CDCD28A6746500180A33 /* XCRemoteSwiftPackageReference "SideMenu" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/jonkykong/SideMenu.git"; + requirement = { + kind = exactVersion; + version = 6.5.0; + }; + }; + AA36CDDC28A6878000180A33 /* XCRemoteSwiftPackageReference "AlamofireImage" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Alamofire/AlamofireImage.git"; + requirement = { + kind = exactVersion; + version = 4.0.0; + }; + }; + E51693C72AFAD4EF0089FB8F /* XCRemoteSwiftPackageReference "mobile-ios-library" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/pia-foss/mobile-ios-library.git"; + requirement = { + branch = "PIA-675_tvOS_compatibility"; + kind = branch; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 35950B302ADD2996006F3CD9 /* Quick */ = { + isa = XCSwiftPackageProductDependency; + package = 35950B2F2ADD2877006F3CD9 /* XCRemoteSwiftPackageReference "Quick" */; + productName = Quick; + }; + 35950B332ADD2EE5006F3CD9 /* Nimble */ = { + isa = XCSwiftPackageProductDependency; + package = 35950B322ADD2EE5006F3CD9 /* XCRemoteSwiftPackageReference "Nimble" */; + productName = Nimble; + }; + 697C59AB2AFD0770008B6212 /* PIALibrary */ = { + isa = XCSwiftPackageProductDependency; + package = 697C59AA2AFD0770008B6212 /* XCRemoteSwiftPackageReference "mobile-ios-library" */; + productName = PIALibrary; + }; + 697C59AD2AFD0786008B6212 /* PIALibrary */ = { + isa = XCSwiftPackageProductDependency; + package = 697C59AA2AFD0770008B6212 /* XCRemoteSwiftPackageReference "mobile-ios-library" */; + productName = PIALibrary; + }; + 697C59AF2AFD0791008B6212 /* PIALibrary */ = { + isa = XCSwiftPackageProductDependency; + package = 697C59AA2AFD0770008B6212 /* XCRemoteSwiftPackageReference "mobile-ios-library" */; + productName = PIALibrary; + }; + 697C59B12AFD079B008B6212 /* PIALibrary */ = { + isa = XCSwiftPackageProductDependency; + package = 697C59AA2AFD0770008B6212 /* XCRemoteSwiftPackageReference "mobile-ios-library" */; + productName = PIALibrary; + }; + AA36CDBA28A6622A00180A33 /* TweetNacl */ = { + isa = XCSwiftPackageProductDependency; + package = AA36CDB928A6622A00180A33 /* XCRemoteSwiftPackageReference "tweetnacl-swiftwrap" */; + productName = TweetNacl; + }; + AA36CDC328A6711300180A33 /* Popover */ = { + isa = XCSwiftPackageProductDependency; + package = AA36CDC228A6711300180A33 /* XCRemoteSwiftPackageReference "Popover" */; + productName = Popover; + }; + AA36CDC828A6733500180A33 /* DZNEmptyDataSet */ = { + isa = XCSwiftPackageProductDependency; + package = AA36CDC728A6733500180A33 /* XCRemoteSwiftPackageReference "DZNEmptyDataSet" */; + productName = DZNEmptyDataSet; + }; + AA36CDCB28A673C900180A33 /* GradientProgressBar */ = { + isa = XCSwiftPackageProductDependency; + package = AA36CDCA28A673C900180A33 /* XCRemoteSwiftPackageReference "GradientProgressBar" */; + productName = GradientProgressBar; + }; + AA36CDCE28A6746500180A33 /* SideMenu */ = { + isa = XCSwiftPackageProductDependency; + package = AA36CDCD28A6746500180A33 /* XCRemoteSwiftPackageReference "SideMenu" */; + productName = SideMenu; + }; + AA36CDDA28A6860F00180A33 /* TweetNacl */ = { + isa = XCSwiftPackageProductDependency; + package = AA36CDB928A6622A00180A33 /* XCRemoteSwiftPackageReference "tweetnacl-swiftwrap" */; + productName = TweetNacl; + }; + AA36CDDD28A6878000180A33 /* AlamofireImage */ = { + isa = XCSwiftPackageProductDependency; + package = AA36CDDC28A6878000180A33 /* XCRemoteSwiftPackageReference "AlamofireImage" */; + productName = AlamofireImage; + }; + AABF826C28AD185E00CDAC64 /* TweetNacl */ = { + isa = XCSwiftPackageProductDependency; + package = AA36CDB928A6622A00180A33 /* XCRemoteSwiftPackageReference "tweetnacl-swiftwrap" */; + productName = TweetNacl; + }; + AABF826E28AD187800CDAC64 /* Popover */ = { + isa = XCSwiftPackageProductDependency; + package = AA36CDC228A6711300180A33 /* XCRemoteSwiftPackageReference "Popover" */; + productName = Popover; + }; + AABF827028AD188700CDAC64 /* AlamofireImage */ = { + isa = XCSwiftPackageProductDependency; + package = AA36CDDC28A6878000180A33 /* XCRemoteSwiftPackageReference "AlamofireImage" */; + productName = AlamofireImage; + }; + AABF827228AE2FF500CDAC64 /* GradientProgressBar */ = { + isa = XCSwiftPackageProductDependency; + package = AA36CDCA28A673C900180A33 /* XCRemoteSwiftPackageReference "GradientProgressBar" */; + productName = GradientProgressBar; + }; + AABF827428AE2FFE00CDAC64 /* SideMenu */ = { + isa = XCSwiftPackageProductDependency; + package = AA36CDCD28A6746500180A33 /* XCRemoteSwiftPackageReference "SideMenu" */; + productName = SideMenu; + }; + AABF827728AE333200CDAC64 /* DZNEmptyDataSet */ = { + isa = XCSwiftPackageProductDependency; + package = AA36CDC728A6733500180A33 /* XCRemoteSwiftPackageReference "DZNEmptyDataSet" */; + productName = DZNEmptyDataSet; + }; + E51693C82AFAD5130089FB8F /* PIALibrary */ = { + isa = XCSwiftPackageProductDependency; + package = E51693C72AFAD4EF0089FB8F /* XCRemoteSwiftPackageReference "mobile-ios-library" */; + productName = PIALibrary; + }; + E51693CA2AFAD51B0089FB8F /* PIALibrary */ = { + isa = XCSwiftPackageProductDependency; + package = E51693C72AFAD4EF0089FB8F /* XCRemoteSwiftPackageReference "mobile-ios-library" */; + productName = PIALibrary; + }; + E51693CC2AFAD5290089FB8F /* PIALibrary */ = { + isa = XCSwiftPackageProductDependency; + package = E51693C72AFAD4EF0089FB8F /* XCRemoteSwiftPackageReference "mobile-ios-library" */; + productName = PIALibrary; + }; + E51693CE2AFAD52F0089FB8F /* PIALibrary */ = { + isa = XCSwiftPackageProductDependency; + package = E51693C72AFAD4EF0089FB8F /* XCRemoteSwiftPackageReference "mobile-ios-library" */; + productName = PIALibrary; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 291C6374183EBC210039EC03 /* Project object */; } diff --git a/PIA VPN.xcodeproj/xcshareddata/xcschemes/PIA VPN WG Tunnel.xcscheme b/PIA VPN.xcodeproj/xcshareddata/xcschemes/PIA VPN WG Tunnel.xcscheme index 117e38cf1..abcf43837 100644 --- a/PIA VPN.xcodeproj/xcshareddata/xcschemes/PIA VPN WG Tunnel.xcscheme +++ b/PIA VPN.xcodeproj/xcshareddata/xcschemes/PIA VPN WG Tunnel.xcscheme @@ -43,6 +43,16 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + diff --git a/PIA VPN.xcodeproj/xcshareddata/xcschemes/PIA VPN dev.xcscheme b/PIA VPN.xcodeproj/xcshareddata/xcschemes/PIA VPN dev.xcscheme index 8baec6c39..8a19b76d3 100644 --- a/PIA VPN.xcodeproj/xcshareddata/xcschemes/PIA VPN dev.xcscheme +++ b/PIA VPN.xcodeproj/xcshareddata/xcschemes/PIA VPN dev.xcscheme @@ -1,7 +1,7 @@ + version = "1.7"> @@ -54,7 +54,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> + shouldUseLaunchSchemeArgsEnv = "NO"> + + + + + + + + + + @@ -75,6 +93,17 @@ ReferencedContainer = "container:PIA VPN.xcodeproj"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PIA VPN.xcworkspace/contents.xcworkspacedata b/PIA VPN.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 0ba381045..000000000 --- a/PIA VPN.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/PIA VPN.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/PIA VPN.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/PIA VPN.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/PIA VPN/AboutComponentCell.swift b/PIA VPN/AboutComponentCell.swift index 21526099c..da839e510 100644 --- a/PIA VPN/AboutComponentCell.swift +++ b/PIA VPN/AboutComponentCell.swift @@ -117,17 +117,17 @@ class AboutLicenseCell: UITableViewCell, Restylable { var moreImage: UIImage? if isExpanded { - moreImage = Asset.buttonUp.image + moreImage = Asset.Images.buttonUp.image textLicense.isScrollEnabled = true } else { - moreImage = Asset.buttonDown.image + moreImage = Asset.Images.buttonDown.image textLicense.isScrollEnabled = false } buttonMore.setImage(moreImage, for: .normal) buttonName.accessibilityTraits = UIAccessibilityTraits.none buttonName.accessibilityLabel = component.name - buttonName.accessibilityHint = L10n.About.Accessibility.Component.expand + buttonName.accessibilityHint = L10n.Localizable.About.Accessibility.Component.expand } // MARK: Actions diff --git a/PIA VPN/AboutViewController.swift b/PIA VPN/AboutViewController.swift index af6dc9f82..14bf0a086 100644 --- a/PIA VPN/AboutViewController.swift +++ b/PIA VPN/AboutViewController.swift @@ -50,7 +50,7 @@ class AboutViewController: AutolayoutViewController { override func viewDidLoad() { super.viewDidLoad() - let textApp = L10n.About.app + let textApp = L10n.Localizable.About.app labelIntro.text = "Copyright © \(AppConfiguration.About.copyright) \(AppConfiguration.About.companyName)\n\(textApp) \(Macros.versionFullString()!)" tableView.scrollsToTop = true @@ -67,7 +67,7 @@ class AboutViewController: AutolayoutViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - styleNavigationBarWithTitle(L10n.Menu.Item.about) + styleNavigationBarWithTitle(L10n.Localizable.Menu.Item.about) } override func viewDidLayoutSubviews() { @@ -92,7 +92,7 @@ class AboutViewController: AutolayoutViewController { // MARK: Helpers @objc private func viewHasRotated() { - styleNavigationBarWithTitle(L10n.Menu.Item.settings) + styleNavigationBarWithTitle(L10n.Localizable.Menu.Item.settings) } private func loadLicensesInBackground() { @@ -122,7 +122,7 @@ class AboutViewController: AutolayoutViewController { tableView.separatorInset = UIEdgeInsets(top: 0, left: 30, bottom: 0, right: 0) Theme.current.applyDividerToSeparator(tableView) - styleNavigationBarWithTitle(L10n.Menu.Item.about) + styleNavigationBarWithTitle(L10n.Localizable.Menu.Item.about) // XXX: for some reason, UITableView is not affected by appearance updates if let viewContainer = viewContainer { Theme.current.applyPrincipalBackground(view) diff --git a/PIA VPN/AccessibilityId.swift b/PIA VPN/AccessibilityId.swift new file mode 100644 index 000000000..a83f3db2c --- /dev/null +++ b/PIA VPN/AccessibilityId.swift @@ -0,0 +1,48 @@ + +import Foundation + +public struct AccessibilityId { + public struct VPNPermission { + public static let screen = "id.vpnPermission.screen" + public static let submit = "id.vpnPermission.ok.button" + } + + public struct Dashboard { + public static let connectionButton = "id.dashboard.connection.button" + } + +} + + +/// This is the same struct `Accessibility` from `PIALibrary` +/// It has been copied over to the VPN ios client app to +/// facilitate e2e testing. +/// In the future, we will move the Welcome and Login ViewControllers and storyboards from `PIALibrary` into vpn ios +/// And this duplication will not be necessary +public struct PIALibraryAccessibility { + public struct Id { + public struct Welcome { + public static let environment = "id.welcome.environment" + } + public struct Login { + public static let submit = "id.login.submit" + public static let submitNew = "id.login.submit.new" + public static let username = "id.login.username" + public static let password = "id.login.submit" + public struct Error { + public static let banner = "id.login.error.banner" + } + } + + public struct Dashboard { + public static let menu = "id.dashboard.menu" + } + public struct Menu { + public static let logout = "id.menu.logout" + } + public struct Dialog { + public static let destructive = "id.dialog.destructive.button" + } + } +} + diff --git a/PIA VPN/AccountObserver.swift b/PIA VPN/AccountObserver.swift index 3a6d3ee0d..0d98dd095 100644 --- a/PIA VPN/AccountObserver.swift +++ b/PIA VPN/AccountObserver.swift @@ -23,6 +23,7 @@ import Foundation import PIALibrary import SwiftyBeaver +import UIKit private let log = SwiftyBeaver.self @@ -83,8 +84,8 @@ class AccountObserver { let note = UNMutableNotificationContent() - note.title = L10n.Expiration.title - note.body = L10n.Expiration.message + note.title = L10n.Localizable.Expiration.title + note.body = L10n.Localizable.Expiration.message note.userInfo = ["date": date] note.sound = .default note.badge = 1 diff --git a/PIA VPN/AccountViewController.swift b/PIA VPN/AccountViewController.swift index 8a181340a..8df114102 100644 --- a/PIA VPN/AccountViewController.swift +++ b/PIA VPN/AccountViewController.swift @@ -70,15 +70,15 @@ class AccountViewController: AutolayoutViewController { override func viewDidLoad() { super.viewDidLoad() - title = L10n.Menu.Item.account - labelUsername.text = L10n.Account.Username.caption - labelRestoreTitle.text = L10n.Account.Restore.title - labelRestoreInfo.text = L10n.Account.Restore.description + title = L10n.Localizable.Menu.Item.account + labelUsername.text = L10n.Localizable.Account.Username.caption + labelRestoreTitle.text = L10n.Localizable.Account.Restore.title + labelRestoreInfo.text = L10n.Localizable.Account.Restore.description imageViewTrash.image = Theme.current.trashIconImage() - buttonRestore.setTitle(L10n.Account.Restore.button.uppercased(), for: .normal) + buttonRestore.setTitle(L10n.Localizable.Account.Restore.button.uppercased(), for: .normal) labelSubscriptions.attributedText = Theme.current.textWithColoredLink( - withMessage: L10n.Account.Subscriptions.message, - link: L10n.Account.Subscriptions.linkMessage) + withMessage: L10n.Localizable.Account.Subscriptions.message, + link: L10n.Localizable.Account.Subscriptions.linkMessage) labelSubscriptions.isUserInteractionEnabled = true viewSafe.layoutMargins = .zero @@ -98,7 +98,7 @@ class AccountViewController: AutolayoutViewController { super.viewWillAppear(animated) // update local state immediately - styleNavigationBarWithTitle(L10n.Menu.Item.account) + styleNavigationBarWithTitle(L10n.Localizable.Menu.Item.account) redisplayAccount() } @@ -114,7 +114,7 @@ class AccountViewController: AutolayoutViewController { } @objc private func viewHasRotated() { - styleNavigationBarWithTitle(L10n.Menu.Item.settings) + styleNavigationBarWithTitle(L10n.Localizable.Menu.Item.settings) } // MARK: Actions @@ -131,11 +131,11 @@ class AccountViewController: AutolayoutViewController { @IBAction private func deleteUserAccount(_ sender: Any?) { let sheet = Macros.alert( - L10n.Account.Delete.Alert.title, - L10n.Account.Delete.Alert.message + L10n.Localizable.Account.Delete.Alert.title, + L10n.Localizable.Account.Delete.Alert.message ) - sheet.addCancelAction(L10n.Global.no) - sheet.addDestructiveActionWithTitle(L10n.Global.yes) { + sheet.addCancelAction(L10n.Localizable.Global.no) + sheet.addDestructiveActionWithTitle(L10n.Localizable.Global.yes) { self.showLoadingAnimation() log.debug("Account: Deleting...") @@ -154,8 +154,8 @@ class AccountViewController: AutolayoutViewController { } } else { self.hideLoadingAnimation() - let sheet = Macros.alert(nil, L10n.Account.Delete.Alert.failureMessage) - sheet.addCancelAction(L10n.Global.ok) + let sheet = Macros.alert(nil, L10n.Localizable.Account.Delete.Alert.failureMessage) + sheet.addCancelAction(L10n.Localizable.Global.ok) self.present(sheet, animated: true, completion: nil) log.debug("Account: Deleting failed...") } @@ -180,15 +180,15 @@ class AccountViewController: AutolayoutViewController { private func handleReceiptFailureWithError(_ error: Error?) { log.error("IAP: Failed to restore payment receipt (error: \(error?.localizedDescription ?? ""))") - let alert = Macros.alert(L10n.Global.error, error?.localizedDescription) - alert.addDefaultAction(L10n.Global.close) + let alert = Macros.alert(L10n.Localizable.Global.error, error?.localizedDescription) + alert.addDefaultAction(L10n.Localizable.Global.close) present(alert, animated: true, completion: nil) } private func handleReceiptSubmissionWithError(_ error: Error?) { if let error = error { - let alert = Macros.alert(L10n.Global.error, error.localizedDescription) - alert.addDefaultAction(L10n.Global.close) + let alert = Macros.alert(L10n.Localizable.Global.error, error.localizedDescription) + alert.addDefaultAction(L10n.Localizable.Global.close) present(alert, animated: true, completion: nil) return } @@ -196,10 +196,10 @@ class AccountViewController: AutolayoutViewController { log.debug("Account: Renewal successfully completed") let alert = Macros.alert( - L10n.Renewal.Success.title, - L10n.Renewal.Success.message + L10n.Localizable.Renewal.Success.title, + L10n.Localizable.Renewal.Success.message ) - alert.addDefaultAction(L10n.Global.close) + alert.addDefaultAction(L10n.Localizable.Global.close) present(alert, animated: true, completion: nil) redisplayAccount() @@ -207,10 +207,10 @@ class AccountViewController: AutolayoutViewController { private func handleBadReceipt() { let alert = Macros.alert( - L10n.Account.Restore.Failure.title, - L10n.Account.Restore.Failure.message + L10n.Localizable.Account.Restore.Failure.title, + L10n.Localizable.Account.Restore.Failure.message ) - alert.addDefaultAction(L10n.Global.close) + alert.addDefaultAction(L10n.Localizable.Global.close) present(alert, animated: true, completion: nil) } @@ -231,9 +231,9 @@ class AccountViewController: AutolayoutViewController { if let userInfo = currentUser?.info { if userInfo.isExpired { - labelExpiryInformation.text = L10n.Account.ExpiryDate.expired + labelExpiryInformation.text = L10n.Localizable.Account.ExpiryDate.expired } else { - labelExpiryInformation.text = L10n.Account.ExpiryDate.information(userInfo.humanReadableExpirationDate()) + labelExpiryInformation.text = L10n.Localizable.Account.ExpiryDate.information(userInfo.humanReadableExpirationDate()) } styleExpirationDate() @@ -264,7 +264,7 @@ class AccountViewController: AutolayoutViewController { self.viewAccountInfo.layer.cornerRadius = 5.0 - styleNavigationBarWithTitle(L10n.Menu.Item.account) + styleNavigationBarWithTitle(L10n.Localizable.Menu.Item.account) if let viewContainer = viewContainer { Theme.current.applyPrincipalBackground(view) @@ -279,7 +279,7 @@ class AccountViewController: AutolayoutViewController { for label in [labelExpiryInformation!] { Theme.current.applySubtitle(label) } - Theme.current.applyUnderline(labelDeleteAccount, with: L10n.Account.delete) + Theme.current.applyUnderline(labelDeleteAccount, with: L10n.Localizable.Account.delete) Theme.current.applyTitle(labelRestoreTitle, appearance: .dark) Theme.current.applySubtitle(labelRestoreInfo) buttonRestore.style(style: TextStyle.textStyle9) diff --git a/PIA VPN/ActiveDedicatedIpHeaderViewCell.swift b/PIA VPN/ActiveDedicatedIpHeaderViewCell.swift index e00d5c51e..98eba246e 100644 --- a/PIA VPN/ActiveDedicatedIpHeaderViewCell.swift +++ b/PIA VPN/ActiveDedicatedIpHeaderViewCell.swift @@ -30,8 +30,8 @@ class ActiveDedicatedIpHeaderViewCell: UITableViewCell { override func awakeFromNib() { super.awakeFromNib() self.backgroundColor = .clear - self.title.text = L10n.Dedicated.Ip.title - self.subtitle.text = L10n.Dedicated.Ip.Limit.title + self.title.text = L10n.Localizable.Dedicated.Ip.title + self.subtitle.text = L10n.Localizable.Dedicated.Ip.Limit.title } func setup() { diff --git a/PIA VPN/ActivityButton.swift b/PIA VPN/ActivityButton.swift new file mode 100644 index 000000000..781d41658 --- /dev/null +++ b/PIA VPN/ActivityButton.swift @@ -0,0 +1,161 @@ +// +// ActivityButton.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/20/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit + +/// A button with an embedded `UIActivityIndicatorView` for simulating a running activity. +public class ActivityButton: UIControl { + + /// :nodoc: + public override var backgroundColor: UIColor? { + get { + return button.backgroundColor + } + set { + button.backgroundColor = newValue + } + } + + /// :nodoc: + public override var isEnabled: Bool { + get { + return button.isEnabled + } + set { + button.isEnabled = newValue + } + } + + /// :nodoc: + public override var accessibilityIdentifier: String? { + get { + return button.accessibilityIdentifier + } + set { + button.accessibilityIdentifier = newValue + } + } + + /// The button text color. + public var textColor: UIColor? { + get { + return button.titleColor(for: .normal) + } + set { + button.setTitleColor(newValue, for: .normal) + } + } + + /// The button title. + public var title: String? { + get { + return button.title(for: .normal) + } + set { + button.setTitle(newValue, for: .normal) + } + } + + /// The button font. + public var font: UIFont? { + get { + return button.titleLabel?.font + } + set { + button.titleLabel?.font = newValue + } + } + + /// The button corner radius. + public var cornerRadius: CGFloat { + get { + return button.layer.cornerRadius + } + set { + button.layer.cornerRadius = newValue + } + } + + /// This is `true` after invoking `startActivity()`. + public var isRunningActivity: Bool { + return activity.isAnimating + } + + private lazy var button = UIButton(type: .custom) + + private lazy var activity = UIActivityIndicatorView(frame: .zero) + + private var previousTitle: String? + + /// :nodoc: + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + backgroundColor = .clear + + button.showsTouchWhenHighlighted = true // XXX: should replicate IB highlight behaviour + button.translatesAutoresizingMaskIntoConstraints = false + button.addTarget(self, action: #selector(handleButtonTouch), for: .touchUpInside) + addSubview(button) + + activity.hidesWhenStopped = true + activity.translatesAutoresizingMaskIntoConstraints = false + addSubview(activity) + + let top = button.topAnchor.constraint(equalTo: topAnchor) + let bottom = button.bottomAnchor.constraint(equalTo: bottomAnchor) + let left = button.leftAnchor.constraint(equalTo: leftAnchor) + let right = button.rightAnchor.constraint(equalTo: rightAnchor) + let activityX = activity.centerXAnchor.constraint(equalTo: button.centerXAnchor) + let activityY = activity.centerYAnchor.constraint(equalTo: button.centerYAnchor) + NSLayoutConstraint.activate([top, bottom, left, right, activityX, activityY]) + } + + /** + Simulates an activity by showing a spinning activity indicator. + */ + public func startActivity() { + guard !activity.isAnimating else { + return + } + previousTitle = title + button.isUserInteractionEnabled = false + title = nil + activity.startAnimating() + } + + /** + Hides the activity indicator previously shown with `startActivity()`. + */ + public func stopActivity() { + guard activity.isAnimating else { + return + } + activity.stopAnimating() + title = previousTitle + button.isUserInteractionEnabled = true + } + + @objc private func handleButtonTouch() { + sendActions(for: .touchUpInside) + } +} diff --git a/PIA VPN/AddCustomNetworksViewController.swift b/PIA VPN/AddCustomNetworksViewController.swift index a33a4d930..be69e0678 100644 --- a/PIA VPN/AddCustomNetworksViewController.swift +++ b/PIA VPN/AddCustomNetworksViewController.swift @@ -127,7 +127,7 @@ extension AddCustomNetworksViewController: UICollectionViewDelegateFlowLayout, U func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: Cells.header, for: indexPath) as! PIAHeaderCollectionViewCell - headerView.setup(withTitle: L10n.Network.Management.Tool.Add.rule, andSubtitle: L10n.Network.Management.Tool.Choose.wifi + L10n.Settings.Hotspothelper.Available.help) + headerView.setup(withTitle: L10n.Localizable.Network.Management.Tool.Add.rule, andSubtitle: L10n.Localizable.Network.Management.Tool.Choose.wifi + L10n.Localizable.Settings.Hotspothelper.Available.help) return headerView } diff --git a/PIA VPN/AddEmailToAccountViewController.swift b/PIA VPN/AddEmailToAccountViewController.swift index 5cf1a9af1..e36555454 100644 --- a/PIA VPN/AddEmailToAccountViewController.swift +++ b/PIA VPN/AddEmailToAccountViewController.swift @@ -62,10 +62,10 @@ class AddEmailToAccountViewController: AutolayoutViewController, BrandableNaviga navigationItem.hidesBackButton = true - labelTitle.text = L10n.Set.Email.Form.email - labelSubtitle.text = L10n.Set.Email.why + labelTitle.text = L10n.Localizable.Set.Email.Form.email + labelSubtitle.text = L10n.Localizable.Set.Email.why - textEmail.placeholder = L10n.Account.Email.placeholder + textEmail.placeholder = L10n.Localizable.Account.Email.placeholder if let currentUser = Client.providers.accountProvider.currentUser, let info = currentUser.info { @@ -77,9 +77,9 @@ class AddEmailToAccountViewController: AutolayoutViewController, BrandableNaviga scrollView.alpha = 0 - labelUsernameCaption.text = L10n.Account.Username.caption + labelUsernameCaption.text = L10n.Localizable.Account.Username.caption labelUsername.text = Client.providers.accountProvider.publicUsername ?? "" - labelPasswordCaption.text = L10n.Set.Email.Password.caption + labelPasswordCaption.text = L10n.Localizable.Set.Email.Password.caption self.styleDismissButton() self.styleContainers() @@ -93,17 +93,17 @@ class AddEmailToAccountViewController: AutolayoutViewController, BrandableNaviga @IBAction private func signUp(_ sender: Any?) { guard let email = textEmail.text?.trimmed(), Validator.validate(email: email) else { - Macros.displayImageNote(withImage: Asset.iconWarning.image, - message: L10n.Set.Email.Error.validation) + Macros.displayImageNote(withImage: Asset.Images.iconWarning.image, + message: L10n.Localizable.Set.Email.Error.validation) self.status = .error(element: textEmail) return } guard termsAndConditionsAgreed else { //present term and conditions - let alert = Macros.alert(L10n.Gdpr.Collect.Data.title, L10n.Gdpr.Collect.Data.description) - alert.addCancelAction(L10n.Global.cancel) - alert.addActionWithTitle(L10n.Gdpr.Accept.Button.title) { + let alert = Macros.alert(L10n.Localizable.Gdpr.Collect.Data.title, L10n.Localizable.Gdpr.Collect.Data.description) + alert.addCancelAction(L10n.Localizable.Global.cancel) + alert.addActionWithTitle(L10n.Localizable.Gdpr.Accept.Button.title) { self.termsAndConditionsAgreed = true self.signUp(nil) } @@ -137,8 +137,8 @@ class AddEmailToAccountViewController: AutolayoutViewController, BrandableNaviga self?.textEmail.text = "" - let alert = Macros.alert(L10n.Global.error, L10n.Account.Set.Email.error) - alert.addDefaultAction(L10n.Global.close) + let alert = Macros.alert(L10n.Localizable.Global.error, L10n.Localizable.Account.Set.Email.error) + alert.addDefaultAction(L10n.Localizable.Global.close) self?.present(alert, animated: true, completion: nil) return @@ -148,7 +148,7 @@ class AddEmailToAccountViewController: AutolayoutViewController, BrandableNaviga self?.textEmail.endEditing(true) //TODO SHOW CREDENTIALS - self?.labelMessage.text = L10n.Set.Email.Success.messageFormat(email) + self?.labelMessage.text = L10n.Localizable.Set.Email.Success.messageFormat(email) self?.labelPassword.text = Client.configuration.tempAccountPassword UIView.animate(withDuration: 0.3, animations: { @@ -176,7 +176,7 @@ class AddEmailToAccountViewController: AutolayoutViewController, BrandableNaviga private func setupAppleSignInUI() { if #available(iOS 13.0, *) { - labelOr.text = L10n.Global.or.uppercased() + labelOr.text = L10n.Localizable.Global.or.uppercased() labelOr.textAlignment = .center let signInWithAppleButton = ASAuthorizationAppleIDButton(type: .signIn, style: Theme.current.palette.appearance == .dark ? .whiteOutline : .black) @@ -252,20 +252,20 @@ class AddEmailToAccountViewController: AutolayoutViewController, BrandableNaviga private func styleConfirmButton() { buttonConfirm.setRounded() buttonConfirm.style(style: TextStyle.Buttons.piaGreenButton) - buttonConfirm.setTitle(L10n.Global.update.uppercased(), + buttonConfirm.setTitle(L10n.Localizable.Global.update.uppercased(), for: []) } private func styleLogoutButton() { Theme.current.applyButtonLabelMediumStyle(logoutButton) - logoutButton.setTitle(L10n.Menu.Logout.title.uppercased(), + logoutButton.setTitle(L10n.Localizable.Menu.Logout.title.uppercased(), for: []) } private func styleDismissButton() { buttonSubmit.setRounded() buttonSubmit.style(style: TextStyle.Buttons.piaGreenButton) - buttonSubmit.setTitle(L10n.Global.close.uppercased(), + buttonSubmit.setTitle(L10n.Localizable.Global.close.uppercased(), for: []) } diff --git a/PIA VPN/AppConfiguration.swift b/PIA VPN/AppConfiguration.swift index 3e6ce758a..ce0f3cc10 100644 --- a/PIA VPN/AppConfiguration.swift +++ b/PIA VPN/AppConfiguration.swift @@ -22,7 +22,9 @@ import Foundation import PIALibrary -import TunnelKit +import TunnelKitCore +import TunnelKitOpenVPN +import UIKit struct AppConfiguration { private static let customClientEnvironment: Client.Environment = .staging @@ -65,7 +67,7 @@ struct AppConfiguration { static let profileName = "Private Internet Access" - static let piaDefaultConfigurationBuilder: OpenVPNTunnelProvider.ConfigurationBuilder = { + static let piaDefaultConfigurationBuilder: OpenVPNProvider.ConfigurationBuilder = { var sessionBuilder = OpenVPN.ConfigurationBuilder() sessionBuilder.renegotiatesAfter = piaRenegotiationInterval sessionBuilder.cipher = .aes128gcm @@ -76,7 +78,7 @@ struct AppConfiguration { sessionBuilder.endpointProtocols = piaAutomaticProtocols sessionBuilder.dnsServers = [] sessionBuilder.usesPIAPatches = true - var builder = OpenVPNTunnelProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build()) + var builder = OpenVPNProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build()) if AppPreferences.shared.useSmallPackets { builder.sessionConfiguration.mtu = AppConstants.OpenVPNPacketSize.smallPacketSize } else { @@ -123,7 +125,7 @@ struct AppConfiguration { } struct Rating { - + static let successDisconnectionsUntilPrompt: Int = 2 static let successConnectionsUntilPrompt: Int = 3 static let successConnectionsUntilPromptAgain: Int = 50 static let errorInConnectionsUntilPrompt: Int = 1 diff --git a/PIA VPN/AppConstants.swift b/PIA VPN/AppConstants.swift index 3432a5407..bd3dd4da1 100644 --- a/PIA VPN/AppConstants.swift +++ b/PIA VPN/AppConstants.swift @@ -89,6 +89,8 @@ struct AppConstants { static let csEmail = "helpdesk+vpnpermissions.ios@privateinternetaccess.com" static let ovpnMigrationURL = URL(string: "https://www.privateinternetaccess.com/helpdesk/kb/articles/removing-openvpn-handshake-and-authentication-settings")! + + static let leakProtectionURL = URL(string: "\(Self.supportURL.absoluteString)/kb/articles/what-is-pia-s-leak-protection-feature-on-ios")! static var stagingEndpointURL: URL? = { guard let path = Bundle.main.path(forResource: "staging", ofType: "endpoint") else { @@ -191,5 +193,9 @@ struct AppConstants { static let connect = "piavpn:connect" static let view = "piavpn:view" } - + + struct Survey { + static let numberOfConnectionsUntilPrompt = 15 + static let formURL = URL(string: "https://privateinternetaccess.typeform.com/to/WTFcN77r")! + } } diff --git a/PIA VPN/AppDelegate.swift b/PIA VPN/AppDelegate.swift index 1f0145230..73a01162c 100644 --- a/PIA VPN/AppDelegate.swift +++ b/PIA VPN/AppDelegate.swift @@ -42,6 +42,7 @@ class AppDelegate: NSObject, UIApplicationDelegate { var window: UIWindow? private var hotspotHelper: PIAHotspotHelper! + private (set) var liveActivityManager: PIAConnectionLiveActivityManagerType? deinit { NotificationCenter.default.removeObserver(self) @@ -55,12 +56,27 @@ class AppDelegate: NSObject, UIApplicationDelegate { application.shortcutItems = [] hotspotHelper = PIAHotspotHelper() _ = hotspotHelper.configureHotspotHelper() - + + instantiateLiveActivityManagerIfNeeded() return true } + + private func instantiateLiveActivityManagerIfNeeded() { + if #available(iOS 16.2, *) { + // Only instantiates the LiveActivities if the Feature Flag for it is enabled + guard AppPreferences.shared.showDynamicIslandLiveActivity else { + liveActivityManager = nil + return + } + + liveActivityManager = PIAConnectionLiveActivityManager.shared + } + } func applicationWillTerminate(_ application: UIApplication) { Bootstrapper.shared.dispose() + + liveActivityManager?.endLiveActivities() } // MARK: Orientations @@ -95,15 +111,15 @@ class AppDelegate: NSObject, UIApplicationDelegate { AppPreferences.shared.didAskToEnableNotifications = true let alert = Macros.alert( - L10n.Notifications.Disabled.title, - L10n.Notifications.Disabled.message + L10n.Localizable.Notifications.Disabled.title, + L10n.Localizable.Notifications.Disabled.message ) - alert.addActionWithTitle(L10n.Notifications.Disabled.settings) { + alert.addActionWithTitle(L10n.Localizable.Notifications.Disabled.settings) { application.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil) } - alert.addCancelAction(L10n.Global.ok) + alert.addCancelAction(L10n.Localizable.Global.ok) window?.rootViewController?.present(alert, animated: true, completion: nil) } @@ -198,6 +214,11 @@ class AppDelegate: NSObject, UIApplicationDelegate { func applicationDidBecomeActive(_ application: UIApplication) { application.applicationIconBadgeNumber = 0 + // Remove the Non compliant Wifi local notification as the app is in foreground now + Macros.removeLocalNotification(NotificationCategory.nonCompliantWifi) + + instantiateLiveActivityManagerIfNeeded() + } private func refreshShortcutItems(in application: UIApplication) { @@ -212,11 +233,11 @@ class AppDelegate: NSObject, UIApplicationDelegate { var itemAsset: ImageAsset! let connectionStatusType = (isNotDisconnected ? ShortcutItem.disconnect : ShortcutItem.connect) - let connectionStatusString = (isNotDisconnected ? L10n.Shortcuts.disconnect : L10n.Shortcuts.connect) + let connectionStatusString = (isNotDisconnected ? L10n.Localizable.Shortcuts.disconnect : L10n.Localizable.Shortcuts.connect) var items: [UIApplicationShortcutItem] = [] - itemAsset = (isNotDisconnected ? Asset.icon3dtDisconnect : Asset.icon3dtConnect) + itemAsset = (isNotDisconnected ? Asset.Images.icon3dtDisconnect : Asset.Images.icon3dtConnect) let connectionStatusIcon = UIApplicationShortcutIcon(templateImageName: itemAsset.name) let connect = UIApplicationShortcutItem( type: connectionStatusType.rawValue, @@ -227,11 +248,11 @@ class AppDelegate: NSObject, UIApplicationDelegate { ) items.append(connect) - itemAsset = Asset.icon3dtSelectRegion + itemAsset = Asset.Images.icon3dtSelectRegion let selectRegionIcon = UIApplicationShortcutIcon(templateImageName: itemAsset.name) let selectRegion = UIApplicationShortcutItem( type: ShortcutItem.selectRegion.rawValue, - localizedTitle: L10n.Shortcuts.selectRegion, + localizedTitle: L10n.Localizable.Shortcuts.selectRegion, localizedSubtitle: nil, icon: selectRegionIcon, userInfo: nil @@ -255,6 +276,8 @@ class AppDelegate: NSObject, UIApplicationDelegate { case .disconnect: if Client.providers.vpnProvider.isVPNConnected { + // Dismiss the Leak Protection alert if present when disconnecting from a Quick Action + dismissLeakProtectionAlert() // this time delay seems to fix a strange issue of the VPN disconnecting and // then automatically reconnecting when it's done from a fresh launch @@ -312,4 +335,22 @@ extension AppDelegate { return UIApplication.shared.delegate as! AppDelegate } + class func getRootViewController() -> UIViewController? { + return AppDelegate.delegate().topViewControllerWithRootViewController(rootViewController: UIApplication.shared.keyWindow?.rootViewController) + } + +} + + +extension AppDelegate { + + private func dismissLeakProtectionAlert() { + if let presentedAlert = window?.rootViewController?.presentedViewController as? UIAlertController { + let leakProtectionAlertTitle = L10n.Localizable.Dashboard.Vpn.Leakprotection.Alert.title + + if presentedAlert.title == leakProtectionAlertTitle { + presentedAlert.dismiss(animated: true) + } + } + } } diff --git a/PIA VPN/AppPreferences.swift b/PIA VPN/AppPreferences.swift index 9388046b4..bae1dd396 100644 --- a/PIA VPN/AppPreferences.swift +++ b/PIA VPN/AppPreferences.swift @@ -22,9 +22,11 @@ import Foundation import PIALibrary -import TunnelKit +import TunnelKitCore +import TunnelKitOpenVPN import SwiftyBeaver import Intents +import UIKit private let log = SwiftyBeaver.self @@ -51,7 +53,8 @@ class AppPreferences { static let useSmallPackets = "UseSmallPackets" static let wireGuardUseSmallPackets = "WireGuardUseSmallPackets" static let ikeV2UseSmallPackets = "IKEV2UseSmallPackets" - + static let usesCustomDNS = "usesCustomDNS" + static let favoriteServerIdentifiersGen4_deprecated = "FavoriteServerIdentifiersGen4" static let regionFilter = "RegionFilter" @@ -80,6 +83,7 @@ class AppPreferences { static let failureConnections = "failureConnections" static let canAskAgainForReview = "canAskAgainForReview" static let lastRatingRejection = "lastRatingRejection" + static let successDisconnections = "successDisconnections" // GEO servers static let showGeoServers = "ShowGeoServers" @@ -91,18 +95,25 @@ class AppPreferences { static let tokenIPRelation_deprecated = "TokenIPRelation" // In app messages - static let stopInAppMessages = "stopInAppMessages" + static let showServiceMessages = "showServiceMessages" // Features static let showsDedicatedIPView = "showsDedicatedIPView" static let disablesMultiDipTokens = "disablesMultiDipTokens" static let checksDipExpirationRequest = "checksDipExpirationRequest" static let showNewInitialScreen = "showNewInitialScreen" + static let showLeakProtection = "showLeakProtection" + static let showLeakProtectionNotifications = "showLeakProtectionNotifications" + static let showDynamicIslandLiveActivity = "showDynamicIslandLiveActivity" + + // Survey + static let userInteractedWithSurvey = "userInteractedWithSurvey" + static let successConnectionsUntilSurvey = "successConnectionsUntilSurvey" // Dev static let appEnvironmentIsProduction = "AppEnvironmentIsProduction" static let stagingVersion = "StagingVersion" - + } static let shared = AppPreferences() @@ -229,7 +240,7 @@ class AppPreferences { var todayWidgetVpnStatus: String? { get { - return defaults.string(forKey: Entries.todayWidgetVpnStatus) ?? L10n.Today.Widget.login + return defaults.string(forKey: Entries.todayWidgetVpnStatus) ?? L10n.Localizable.Today.Widget.login } set { defaults.set(newValue, forKey: Entries.todayWidgetVpnStatus) @@ -308,6 +319,15 @@ class AppPreferences { } } + var usesCustomDNS: Bool { + get { + return defaults.bool(forKey: Entries.usesCustomDNS) + } + set { + defaults.set(newValue, forKey: Entries.usesCustomDNS) + } + } + var dedicatedTokenIPReleation: [String: String] { get { let keychain = PIALibrary.Keychain(team: AppConstants.teamId, group: AppConstants.appGroup) @@ -438,6 +458,15 @@ class AppPreferences { } } + var successDisconnections: Int { + get { + return defaults.integer(forKey: Entries.successDisconnections) + } + set { + defaults.set(newValue, forKey: Entries.successDisconnections) + } + } + var appVersion: String? { get { return defaults.string(forKey: Entries.appVersion) @@ -456,12 +485,12 @@ class AppPreferences { } } - var stopInAppMessages: Bool { + var showServiceMessages: Bool { get { - return defaults.bool(forKey: Entries.stopInAppMessages) + return defaults.bool(forKey: Entries.showServiceMessages) } set { - defaults.set(newValue, forKey: Entries.stopInAppMessages) + defaults.set(newValue, forKey: Entries.showServiceMessages) } } @@ -492,6 +521,33 @@ class AppPreferences { } } + var showLeakProtection: Bool { + get { + return defaults.bool(forKey: Entries.showLeakProtection) + } + set { + defaults.set(newValue, forKey: Entries.showLeakProtection) + } + } + + var showLeakProtectionNotifications: Bool { + get { + return defaults.bool(forKey: Entries.showLeakProtectionNotifications) + } + set { + defaults.set(newValue, forKey: Entries.showLeakProtectionNotifications) + } + } + + var showDynamicIslandLiveActivity: Bool { + get { + return defaults.bool(forKey: Entries.showDynamicIslandLiveActivity) + } + set { + defaults.set(newValue, forKey: Entries.showDynamicIslandLiveActivity) + } + } + var checksDipExpirationRequest: Bool { get { return defaults.bool(forKey: Entries.checksDipExpirationRequest) @@ -518,7 +574,25 @@ class AppPreferences { defaults.set(newValue, forKey: Entries.stagingVersion) } } - + + var userInteractedWithSurvey: Bool { + get { + return defaults.bool(forKey: Entries.userInteractedWithSurvey) + } + set { + defaults.set(newValue, forKey: Entries.userInteractedWithSurvey) + } + } + + var successConnectionsUntilSurvey: Int? { + get { + return defaults.value(forKey: Entries.successConnectionsUntilSurvey) as? Int + } + set { + defaults.set(newValue, forKey: Entries.successConnectionsUntilSurvey) + } + } + private init() { guard let defaults = UserDefaults(suiteName: AppConstants.appGroup) else { fatalError("Unable to initialize app preferences") @@ -534,7 +608,7 @@ class AppPreferences { Entries.themeCode: ThemeCode.light.rawValue, Entries.useConnectSiriShortcuts: false, Entries.useDisconnectSiriShortcuts: false, - Entries.todayWidgetButtonTitle: L10n.Today.Widget.login, + Entries.todayWidgetButtonTitle: L10n.Localizable.Today.Widget.login, Entries.todayWidgetVpnProtocol: IKEv2Profile.vpnType, Entries.todayWidgetVpnPort: "500", Entries.todayWidgetVpnSocket: "UDP", @@ -546,15 +620,18 @@ class AppPreferences { Entries.useSmallPackets: false, Entries.wireGuardUseSmallPackets: true, Entries.ikeV2UseSmallPackets: true, + Entries.usesCustomDNS: false, Entries.canAskAgainForReview: false, + Entries.successDisconnections: 0, Entries.successConnections: 0, Entries.failureConnections: 0, Entries.showGeoServers: true, Entries.dismissedMessages: [], - Entries.stopInAppMessages: false, + Entries.showServiceMessages: false, Entries.showsDedicatedIPView: true, Entries.disablesMultiDipTokens: true, Entries.checksDipExpirationRequest: true, + Entries.userInteractedWithSurvey: false, Entries.stagingVersion: 0, Entries.appEnvironmentIsProduction: Client.environment == .production ? true : false, ]) @@ -590,8 +667,8 @@ class AppPreferences { func migrateOVPN() { - guard let currentOpenVPNConfiguration = Client.preferences.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNTunnelProvider.Configuration ?? - Client.preferences.defaults.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNTunnelProvider.Configuration else { + guard let currentOpenVPNConfiguration = Client.preferences.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNProvider.Configuration ?? + Client.preferences.defaults.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNProvider.Configuration else { return } @@ -613,7 +690,7 @@ class AppPreferences { } if shouldUpdate { - var builder = OpenVPNTunnelProvider.ConfigurationBuilder(sessionConfiguration: pendingOpenVPNConfiguration.build()) + var builder = OpenVPNProvider.ConfigurationBuilder(sessionConfiguration: pendingOpenVPNConfiguration.build()) if AppPreferences.shared.useSmallPackets { builder.sessionConfiguration.mtu = AppConstants.OpenVPNPacketSize.smallPacketSize } else { @@ -771,18 +848,24 @@ class AppPreferences { quickSettingPrivateBrowserVisible = true useSmallPackets = false ikeV2UseSmallPackets = true + usesCustomDNS = false wireGuardUseSmallPackets = true todayWidgetVpnProtocol = IKEv2Profile.vpnType todayWidgetVpnPort = "500" todayWidgetVpnSocket = "UDP" todayWidgetTrustedNetwork = false Client.resetServers(completionBlock: {_ in }) + successDisconnections = 0 + successConnections = 0 failureConnections = 0 showGeoServers = true - stopInAppMessages = false + showServiceMessages = false dedicatedTokenIPReleation = [:] appEnvironmentIsProduction = Client.environment == .production ? true : false MessagesManager.shared.reset() + userInteractedWithSurvey = false + successConnectionsUntilSurvey = nil + Client.preferences.lastKnownException = nil } func clean() { @@ -793,8 +876,8 @@ class AppPreferences { useDisconnectSiriShortcuts = false connectShortcut = nil disconnectShortcut = nil - todayWidgetVpnStatus = L10n.Today.Widget.login - todayWidgetButtonTitle = L10n.Today.Widget.login + todayWidgetVpnStatus = L10n.Localizable.Today.Widget.login + todayWidgetButtonTitle = L10n.Localizable.Today.Widget.login todayWidgetVpnProtocol = IKEv2Profile.vpnType todayWidgetVpnPort = "500" todayWidgetVpnSocket = "UDP" @@ -805,17 +888,23 @@ class AppPreferences { quickSettingPrivateBrowserVisible = true useSmallPackets = false ikeV2UseSmallPackets = true + usesCustomDNS = false wireGuardUseSmallPackets = true let preferences = Client.preferences.editable().reset() preferences.commit() Client.resetServers(completionBlock: {_ in }) + successDisconnections = 0 + successConnections = 0 failureConnections = 0 showGeoServers = true - stopInAppMessages = false + showServiceMessages = false dismissedMessages = [] dedicatedTokenIPReleation = [:] MessagesManager.shared.reset() appEnvironmentIsProduction = Client.environment == .production ? true : false + userInteractedWithSurvey = false + successConnectionsUntilSurvey = nil + Client.preferences.lastKnownException = nil } // + (void)eraseForTesting; @@ -858,4 +947,13 @@ class AppPreferences { } } } + + // MARK: Connections + func incrementSuccessConnections() { + successConnections += 1 + } + + func incrementSuccessDisconnections() { + successDisconnections += 1 + } } diff --git a/PIA VPN/AutolayoutViewController.swift b/PIA VPN/AutolayoutViewController.swift new file mode 100644 index 000000000..712bb410b --- /dev/null +++ b/PIA VPN/AutolayoutViewController.swift @@ -0,0 +1,347 @@ +// +// AutolayoutViewControllers.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/20/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import Lottie +import PIALibrary +/// Declares a generic, dismissable modal controller. +public protocol ModalController: class { + + /** + Dismisses the modal controller. + */ + func dismissModal() +} + +public protocol AnimatingLoadingDelegate: class { + func showLoadingAnimation() + func hideLoadingAnimation() +} + +/// Enum used to determinate the status of the view controller and apply effects over the UI elements +public enum ViewControllerStatus { + case initial + case restore(element: UIView) + case error(element: UIView) +} + +/// Base view controller with dynamic constraints and restyling support. +/// +/// - Seealso: `Theme` +open class AutolayoutViewController: UIViewController, ModalController, Restylable { + + /// The outlet to the main view container (optional). + /// + /// - Seealso: `ThemeStrategy.autolayoutContainerMargins(for:)` + @IBOutlet public weak var viewContainer: UIView? + + /// :nodoc: + open override var preferredStatusBarStyle: UIStatusBarStyle { + return Theme.current.statusBarAppearance(for: self) + } + + /// The initial status of the view controller. Every time the var changes the value, we reload the UI of the form element given as parameter. + /// Example of use: self.status = .error(element: textEmail) + open var status: ViewControllerStatus = .initial { + didSet { reloadFormElements() } + } + + deinit { + NotificationCenter.default.removeObserver(self) + } + + /// :nodoc: + open override func viewDidLoad() { + super.viewDidLoad() + + if let viewContainer = viewContainer { + Theme.current.applyPrincipalBackground(viewContainer) + } + + NotificationCenter.default.addObserver(self, selector: #selector(viewShouldRestyle), name: .PIAThemeDidChange, object: nil) + viewShouldRestyle() + } + + /// :nodoc: + open override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + refreshOrientationConstraints(size: view.bounds.size) + } + + open override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + //MARK: - iOS13 Dark mode + if #available(iOS 13.0, *) { + Macros.postNotification(.PIAThemeShouldChange) + } + } + + private func refreshOrientationConstraints(size: CGSize) { + if let viewContainer = viewContainer { + let orientation: UIInterfaceOrientationMask = (isLandscape ? .landscape : .portrait) + viewContainer.layoutMargins = Theme.current.autolayoutContainerMargins(for: orientation) + } + didRefreshOrientationConstraints() + } + + // MARK: Public interface + + /// Shortcut for signalling landscape orientation. + public var isLandscape: Bool { + return (view.bounds.size.width > view.bounds.size.height) + } + + /** + Called right after refreshing the orientation contraints, e.g. when the device rotates. + */ + open func didRefreshOrientationConstraints() { + } + + // MARK: ModalController + + /// :nodoc: + @objc open func dismissModal() { + dismiss(animated: true, completion: nil) + } + + // MARK: Restylable + + /// :nodoc: + @objc open func viewShouldRestyle() { + Theme.current.applyNavigationBarStyle(to: self) + Theme.current.applyPrincipalBackground(view) + if let viewContainer = viewContainer { + Theme.current.applyPrincipalBackground(viewContainer) + } + setNeedsStatusBarAppearanceUpdate() + } + + private func reloadFormElements() { + switch status { + case .initial: + break + case .restore(let element): + restoreFormElementBorder(element) + case .error(let element): + updateFormElementBorder(element) + } + } + + private func restoreFormElementBorder(_ element: UIView) { + if let element = element as? UITextField { + Theme.current.applyInput(element) + element.rightView = nil + } + } + + private func updateFormElementBorder(_ element: UIView) { + if let element = element as? UITextField { + Theme.current.applyInputError(element) + let iconWarning = UIImageView(image:Asset.Images.iconWarning.image.withRenderingMode(.alwaysTemplate)) + iconWarning.tintColor = .piaRed + element.rightView = iconWarning + } + } + + public func styleNavigationBarWithTitle(_ title: String) { + + let currentStatus = Client.providers.vpnProvider.vpnStatus + + switch currentStatus { + case .connected: + let titleLabelView = UILabel(frame: CGRect.zero) + titleLabelView.style(style: TextStyle.textStyle6) + titleLabelView.text = title + if let navController = navigationController { + Theme.current.applyCustomNavigationBar(navController.navigationBar, + withTintColor: .white, + andBarTintColors: [UIColor.piaGreen, + UIColor.piaGreenDark20]) + } + let size = titleLabelView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) + titleLabelView.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height) + navigationItem.titleView = titleLabelView + setNeedsStatusBarAppearanceUpdate() + + default: + let titleLabelView = UILabel(frame: CGRect.zero) + titleLabelView.style(style: Theme.current.palette.appearance == .dark ? + TextStyle.textStyle6 : + TextStyle.textStyle7) + titleLabelView.text = title + if let navigationController = navigationController { + Theme.current.applyCustomNavigationBar(navigationController.navigationBar, + withTintColor: nil, + andBarTintColors: nil) + } + + let size = titleLabelView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) + titleLabelView.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height) + navigationItem.titleView = titleLabelView + setNeedsStatusBarAppearanceUpdate() + + } + } + + @objc public func back(_ sender: Any?) { + self.navigationController?.popViewController(animated: true) + } + +} + +extension AutolayoutViewController: AnimatingLoadingDelegate { + + private struct LottieRepos { + static var graphLoad: AnimationView? + static var containerView: UIView? + } + + var graphLoad: AnimationView? { + get { + return objc_getAssociatedObject(self, &LottieRepos.graphLoad) as? AnimationView + } + set { + if let unwrappedValue = newValue { + objc_setAssociatedObject(self, &LottieRepos.graphLoad, unwrappedValue as AnimationView?, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + } + + var containerView: UIView? { + get { + return LottieRepos.containerView + } + set { + if let unwrappedValue = newValue { + LottieRepos.containerView = unwrappedValue + } + } + } + + @objc public func showLoadingAnimation() { + if graphLoad == nil { + containerView = UIView(frame: UIScreen.main.bounds) + containerView?.backgroundColor = Theme.current.palette.appearance == .dark ? + UIColor.black.withAlphaComponent(0.72) : + UIColor.piaGrey1.withAlphaComponent(0.75) + graphLoad = AnimationView(name: "pia-spinner") + } + addLoadingAnimation() + } + + private func addLoadingAnimation() { + graphLoad?.loopMode = .loop + if let graphLoad = graphLoad, + let containerView = containerView { + if let key = self.navigationController?.view { + key.addSubview(containerView) + key.addSubview(graphLoad) + } + setLoadingConstraints() + graphLoad.play() + } + } + + @objc public func hideLoadingAnimation() { + graphLoad?.stop() + graphLoad?.removeFromSuperview() + containerView?.removeFromSuperview() + } + + private func setLoadingConstraints() { + if let graphLoad = graphLoad, + let keyView = self.navigationController?.view, + let containerView = containerView { + + containerView.translatesAutoresizingMaskIntoConstraints = false + graphLoad.translatesAutoresizingMaskIntoConstraints = false + + NSLayoutConstraint(item: containerView, + attribute: .left, + relatedBy: .equal, + toItem: keyView, + attribute: .left, + multiplier: 1.0, + constant: 0.0).isActive = true + + NSLayoutConstraint(item: containerView, + attribute: .right, + relatedBy: .equal, + toItem: keyView, + attribute: .right, + multiplier: 1.0, + constant: 0.0).isActive = true + + NSLayoutConstraint(item: containerView, + attribute: .top, + relatedBy: .equal, + toItem: keyView, + attribute: .top, + multiplier: 1.0, + constant: 0.0).isActive = true + + NSLayoutConstraint(item: containerView, + attribute: .bottom, + relatedBy: .equal, + toItem: keyView, + attribute: .bottom, + multiplier: 1.0, + constant: 0.0).isActive = true + + NSLayoutConstraint(item: graphLoad, + attribute: .centerX, + relatedBy: .equal, + toItem: containerView, + attribute: .centerX, + multiplier: 1.0, + constant: 0.0).isActive = true + + NSLayoutConstraint(item: graphLoad, + attribute: .centerY, + relatedBy: .equal, + toItem: containerView, + attribute: .centerY, + multiplier: 1.0, + constant: 0.0).isActive = true + + let lottieWidth = UIScreen.main.bounds.width/4 + + NSLayoutConstraint(item: graphLoad, + attribute: .width, + relatedBy: .equal, + toItem: nil, + attribute: .width, + multiplier: 1.0, + constant: lottieWidth).isActive = true + + NSLayoutConstraint(item: graphLoad, + attribute: .height, + relatedBy: .equal, + toItem: nil, + attribute: .height, + multiplier: 1.0, + constant: lottieWidth).isActive = true + + } + } + +} diff --git a/PIA VPN/Bootstrapper.swift b/PIA VPN/Bootstrapper.swift index a1243066a..3d974406d 100644 --- a/PIA VPN/Bootstrapper.swift +++ b/PIA VPN/Bootstrapper.swift @@ -22,14 +22,10 @@ import Foundation import PIALibrary -import TunnelKit +import TunnelKitCore +import TunnelKitOpenVPN import SwiftyBeaver import PIAWireguard -#if PIA_DEV -import Firebase -import Fabric -import Crashlytics -#endif class Bootstrapper { @@ -39,32 +35,47 @@ class Bootstrapper { } private var isSimulator: Bool { - #if arch(i386) || arch(x86_64) + #if targetEnvironment(simulator) return true #else return false #endif } + + var isDevelopmentBuild: Bool { + #if PIA_DEV + return true + #else + return false + #endif + } + + /// Update the values of the flags from the CSI server + private func updateFeatureFlagsForReleaseIfNeeded() { + // Some feature flags like Leak Protection are controled from the Developer menu on Dev builds. + // So we skip updating the flag from the server on dev builds + guard !isDevelopmentBuild else { return } + + // Leak Protection feature flags + AppPreferences.shared.showLeakProtection = Client.configuration.featureFlags.contains(Client.FeatureFlags.showLeakProtection) + AppPreferences.shared.showLeakProtectionNotifications = Client.configuration.featureFlags.contains(Client.FeatureFlags.showLeakProtectionNotifications) + + // DynamicIsland LiveActivity + AppPreferences.shared.showDynamicIslandLiveActivity = Client.configuration.featureFlags.contains(Client.FeatureFlags.showDynamicIslandLiveActivity) + + } func bootstrap() { let console = ConsoleDestination() #if PIA_DEV console.minLevel = .debug - - if let path = Bundle.main.url(forResource: "GoogleService-Info", withExtension: "plist"), - let plist = NSDictionary(contentsOf: path) as? [String: Any], - plist.count > 0 { - FirebaseApp.configure() - Fabric.sharedSDK().debug = true - Fabric.with([Crashlytics.self()]) - } #else console.minLevel = .info #endif SwiftyBeaver.addDestination(console) // Load the database first - Client.database = Client.Database(team: AppConstants.teamId, group: AppConstants.appGroup) + Client.database = Client.Database(group: AppConstants.appGroup) // Check if should clean the account after delete the app and install again if Client.providers.accountProvider.shouldCleanAccount { @@ -142,8 +153,13 @@ class Bootstrapper { AppPreferences.shared.checksDipExpirationRequest = Client.configuration.featureFlags.contains(Client.FeatureFlags.checkDipExpirationRequest) AppPreferences.shared.disablesMultiDipTokens = Client.configuration.featureFlags.contains(Client.FeatureFlags.disableMultiDipTokens) AppPreferences.shared.showNewInitialScreen = Client.configuration.featureFlags.contains(Client.FeatureFlags.showNewInitialScreen) + + + /// Updates the feature flags values to the ones set on the server only on Release builds. + /// (like Leak protection feature) + self.updateFeatureFlagsForReleaseIfNeeded() + }) - MessagesManager.shared.refreshMessages() //FORCE THE MIGRATION TO GEN4 if Client.providers.vpnProvider.needsMigrationToGEN4() { @@ -230,7 +246,7 @@ class Bootstrapper { if AppPreferences.shared.checksDipExpirationRequest, let dipToken = Client.providers.serverProvider.dipTokens?.first { Client.providers.serverProvider.handleDIPTokenExpiration(dipToken: dipToken, nil) } - + setupExceptionHandler() } private func setDefaultPlanProducts() { @@ -241,7 +257,13 @@ class Bootstrapper { func dispose() { Client.dispose() } - + + private func setupExceptionHandler() { + NSSetUncaughtExceptionHandler { exception in + Client.preferences.lastKnownException = "$exception,\n\(exception.callStackSymbols.joined(separator: "\n"))" + } + } + // MARK: Certificate func rsa4096Certificate() -> String? { @@ -256,10 +278,17 @@ class Bootstrapper { } @objc private func vpnStatusDidChange(notification: Notification) { - guard (Client.providers.vpnProvider.vpnStatus == .connected) else { - return + let vpnStatus = Client.providers.vpnProvider.vpnStatus + switch vpnStatus { + case .connected: + AppPreferences.shared.incrementSuccessConnections() + UserSurveyManager.shared.handleConnectionSuccess() + case .disconnected: + AppPreferences.shared.incrementSuccessDisconnections() + default: + break } - RatingManager.shared.logSuccessConnection() + RatingManager.shared.handleConnectionStatusChanged() } @objc private func internetReachable(notification: Notification) { @@ -267,7 +296,7 @@ class Bootstrapper { } @objc private func internetUnreachable(notification: Notification) { - Macros.displayStickyNote(withMessage: L10n.Global.unreachable, - andImage: Asset.iconWarning.image) + Macros.displayStickyNote(withMessage: L10n.Localizable.Global.unreachable, + andImage: Asset.Images.iconWarning.image) } } diff --git a/PIA VPN/BorderedTextField.swift b/PIA VPN/BorderedTextField.swift new file mode 100644 index 000000000..7bb16f5e3 --- /dev/null +++ b/PIA VPN/BorderedTextField.swift @@ -0,0 +1,219 @@ +// +// BorderedTextField.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/20/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit + +/// An `UITextField` specialization with a border that can highlight while editing. +public class BorderedTextField: UITextField { + private static let allowedReadonlyActions: Set = Set([ + #selector(select(_:)), + #selector(selectAll(_:)), + #selector(copy(_:)) + ]) + + private static let allowedActions: Set = Set([ + #selector(select(_:)), + #selector(selectAll(_:)), + #selector(copy(_:)), + #selector(cut(_:)), + #selector(paste(_:)) + ]) + + private static let allowedSecureActions: Set = Set([ + #selector(paste(_:)) + ]) + + /// :nodoc: + public override var placeholder: String? { + didSet { + reloadPlaceholder() + } + } + + /// The default color of the border. + public var borderColor: UIColor? { + didSet { + if (!highlightsWhileEditing || !isEditing) { + self.layer.borderColor = borderColor?.cgColor + } + reloadPlaceholder() + } + } + + /// The color of the border while highlighted. + public var highlightedBorderColor: UIColor? = .blue { + didSet { + if (highlightsWhileEditing && isEditing) { + self.layer.borderColor = highlightedBorderColor?.cgColor + } + } + } + + /// When `true`, the text field border highlights while editing. + public var highlightsWhileEditing = true + + /// When `true`, the text field can be edited. + public var isEditable = true + + /// :nodoc: + public override var delegate: UITextFieldDelegate? { + get { + return realDelegate + } + set { + if (newValue as? BorderedTextField == self) { + super.delegate = newValue + } else { + realDelegate = newValue + } + } + } + + /// :nodoc: + public override func awakeFromNib() { + super.awakeFromNib() + rightViewMode = .unlessEditing + borderStyle = .none + textColor = .darkText + self.delegate = self + } + + private weak var viewBorder: UIView? + + private weak var realDelegate: UITextFieldDelegate? + + /// :nodoc: + public override func willMove(toSuperview newSuperview: UIView?) { + super.willMove(toSuperview: newSuperview) + + self.layer.cornerRadius = 6.0 + self.layer.borderColor = borderColor?.cgColor + self.layer.borderWidth = 1 + + reloadPlaceholder() + + } + + /// :nodoc: + public override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool { + let allowed: Set + if isSecureTextEntry { + guard isEditable else { + return false + } + allowed = BorderedTextField.allowedSecureActions + } else { + if isEditable { + allowed = BorderedTextField.allowedActions + } else { + allowed = BorderedTextField.allowedReadonlyActions + } + } + return allowed.contains(action) + } + + private func reloadPlaceholder() { + if let placeholder = placeholder, let placeholderColor = borderColor { + let attributes: [NSAttributedString.Key: Any] = [ + .foregroundColor: placeholderColor + ] + attributedPlaceholder = NSAttributedString(string: placeholder, attributes: attributes) + } + } + + override public func textRect(forBounds bounds: CGRect) -> CGRect { + return bounds.inset(by: UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)) + } + override public func editingRect(forBounds bounds: CGRect) -> CGRect { + return bounds.inset(by: UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)) + } + override public func placeholderRect(forBounds bounds: CGRect) -> CGRect { + return bounds.inset(by: UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)) + } + + public override func rightViewRect(forBounds bounds: CGRect) -> CGRect { + var rightViewRect = super.rightViewRect(forBounds: bounds) + rightViewRect.origin.x -= 16 + return rightViewRect + } + +} + +// XXX: hack to inject self delegate +/// :nodoc: +extension BorderedTextField: UITextFieldDelegate { + public func textFieldShouldClear(_ textField: UITextField) -> Bool { + if let method = realDelegate?.textFieldShouldClear { + return method(textField) + } + return true + } + + public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + guard let borderedTextField = textField as? BorderedTextField, borderedTextField.isEditable else { + return false + } + if let method = realDelegate?.textField(_:shouldChangeCharactersIn:replacementString:) { + return method(textField, range, string) + } + return true + } + + public func textFieldShouldReturn(_ textField: UITextField) -> Bool { + if let method = realDelegate?.textFieldShouldReturn(_:) { + return method(textField) + } + return true + } + + public func textFieldDidBeginEditing(_ textField: UITextField) { + if highlightsWhileEditing { + self.layer.borderColor = highlightedBorderColor?.cgColor + } + + if let method = realDelegate?.textFieldDidBeginEditing(_:) { + return method(textField) + } + } + + public func textFieldDidEndEditing(_ textField: UITextField) { + self.layer.borderColor = borderColor?.cgColor + + if let method = realDelegate?.textFieldDidEndEditing(_:) { + return method(textField) + } + } + + public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { + if let method = realDelegate?.textFieldShouldEndEditing { + return method(textField) + } + return true + } + + public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { + if let method = realDelegate?.textFieldShouldEndEditing(_:) { + return method(textField) + } + return true + } +} diff --git a/PIA VPN/CAGradientLayer+Image.swift b/PIA VPN/CAGradientLayer+Image.swift new file mode 100644 index 000000000..2c9197c54 --- /dev/null +++ b/PIA VPN/CAGradientLayer+Image.swift @@ -0,0 +1,37 @@ +// +// CAGradientLayer+Image.swift +// PIA VPN +// +// Created by Said Rehouni on 8/11/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import UIKit + +extension CAGradientLayer { + + convenience init(frame: CGRect, colors: [UIColor]) { + self.init() + self.frame = frame + self.colors = [] + for color in colors { + self.colors?.append(color.cgColor) + } + startPoint = CGPoint(x: 0, y: 0) + endPoint = CGPoint(x: 0, y: 1) + } + + func createGradientImage() -> UIImage? { + + var image: UIImage? = nil + UIGraphicsBeginImageContext(bounds.size) + if let context = UIGraphicsGetCurrentContext() { + render(in: context) + image = UIGraphicsGetImageFromCurrentImageContext() + } + UIGraphicsEndImageContext() + return image + } + +} diff --git a/PIA VPN/CardFactory.swift b/PIA VPN/CardFactory.swift index 90f16e03b..d359fc1ab 100644 --- a/PIA VPN/CardFactory.swift +++ b/PIA VPN/CardFactory.swift @@ -22,6 +22,7 @@ import Foundation import PIALibrary import PIAWireguard +import UIKit struct CardFactory { @@ -40,11 +41,11 @@ struct CardFactory { private static let availableCards = [ Card("3.7.1", - L10n.Card.Wireguard.title, - L10n.Card.Wireguard.description, + L10n.Localizable.Card.Wireguard.title, + L10n.Localizable.Card.Wireguard.description, "wg-background-", "wg-main", - L10n.Card.Wireguard.Cta.activate, + L10n.Localizable.Card.Wireguard.Cta.activate, URL(string: "https://www.privateinternetaccess.com/blog/wireguide-all-about-the-wireguard-vpn-protocol/"), { guard let rootView = AppDelegate.delegate().topViewControllerWithRootViewController(rootViewController: UIApplication.shared.keyWindow?.rootViewController) else { diff --git a/PIA VPN/Client+Storyboard.swift b/PIA VPN/Client+Storyboard.swift new file mode 100644 index 000000000..621d6b1f4 --- /dev/null +++ b/PIA VPN/Client+Storyboard.swift @@ -0,0 +1,20 @@ +// +// Client+Storyboard.swift +// PIA VPN +// +// Created by Said Rehouni on 26/10/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import PIALibrary +import UIKit + +extension Client { + /** + Returns the Signup Storyboard owned by the library to be used by the clients + */ + public static func signupStoryboard() -> UIStoryboard { + UIStoryboard(name: "Signup", bundle: Bundle.main) + } +} diff --git a/PIA VPN/ClientError+Localization.swift b/PIA VPN/ClientError+Localization.swift new file mode 100644 index 000000000..a96b4509f --- /dev/null +++ b/PIA VPN/ClientError+Localization.swift @@ -0,0 +1,21 @@ +// +// ClientError+Localization.swift +// +// +// Created by Juan Docal on 2022-08-11. +// + +import Foundation +import PIALibrary + +extension ClientError: LocalizedError { + public var errorDescription: String? { + switch self { + case .sandboxPurchase: + return NSLocalizedString(L10n.Signup.Failure.Purchase.Sandbox.message, + comment: L10n.Signup.Failure.Purchase.Sandbox.message) + default: + return nil + } + } +} diff --git a/PIA VPN/ConfirmVPNPlanViewController.swift b/PIA VPN/ConfirmVPNPlanViewController.swift new file mode 100644 index 000000000..20fdaaff5 --- /dev/null +++ b/PIA VPN/ConfirmVPNPlanViewController.swift @@ -0,0 +1,267 @@ +// +// ConfirmVPNPlanViewController.swift +// PIALibrary-iOS +// +// Created by Jose Antonio Blaya Garcia on 14/11/2018. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import SwiftyBeaver +import AuthenticationServices +import PIALibrary + +private let log = SwiftyBeaver.self + +public class ConfirmVPNPlanViewController: AutolayoutViewController, BrandableNavigationBar, WelcomeChild { + + @IBOutlet private weak var buttonConfirm: PIAButton! + @IBOutlet private weak var textEmail: BorderedTextField! + @IBOutlet private weak var labelTitle: UILabel! + @IBOutlet private weak var labelSubtitle: UILabel! + @IBOutlet private weak var addEmailContainer: UIView! + + private var labelOr = UILabel() + private var signupEmail: String? + private var signupTransaction: InAppTransaction? + var metadata: SignupMetadata! + weak var completionDelegate: WelcomeCompletionDelegate? + var omitsSiblingLink = false + var termsAndConditionsAgreed = false + + var preset: Preset? + + deinit { + NotificationCenter.default.removeObserver(self) + } + + override public func viewDidLoad() { + super.viewDidLoad() + + guard let preset = self.preset else { + fatalError("Preset not propagated") + } + + navigationItem.hidesBackButton = true + + labelTitle.text = L10n.Welcome.Purchase.Confirm.Form.email + labelSubtitle.text = L10n.Welcome.Purchase.Email.why + + textEmail.placeholder = L10n.Welcome.Purchase.Email.placeholder + textEmail.text = preset.purchaseEmail + self.styleConfirmButton() + + if #available(iOSApplicationExtension 13.0, *) { + setupAppleSignInUI() + } + + } + + @IBAction private func signUp(_ sender: Any?) { + + guard let email = textEmail.text?.trimmed(), Validator.validate(email: email) else { + signupEmail = nil + Macros.displayImageNote(withImage: Asset.Images.iconWarning.image, + message: L10n.Welcome.Purchase.Error.validation) + self.status = .error(element: textEmail) + return + } + + guard termsAndConditionsAgreed else { + //present term and conditions + self.performSegue(withIdentifier: StoryboardSegue.Signup.presentGDPRTermsSegue.rawValue, + sender: nil) + return + } + + self.status = .restore(element: textEmail) + + self.showLoadingAnimation() + self.disableInteractions() + + log.debug("Account: Modifying account email...") + + metadata.title = L10n.Signup.InProgress.title + metadata.bodyImage = Asset.Images.imagePurchaseSuccess.image + metadata.bodyTitle = L10n.Signup.Success.title + metadata.bodySubtitle = L10n.Signup.Success.messageFormat(email) + + let request = UpdateAccountRequest(email: email) + + var password = "" + if let currentPassword = metadata.user?.credentials.password { + password = currentPassword + } + + Client.providers.accountProvider.update(with: request, + resetPassword: false, + andPassword: password) { [weak self] (info, error) in + self?.hideLoadingAnimation() + self?.enableInteractions() + + guard let _ = info else { + if let error = error { + log.error("Account: Failed to modify account email (error: \(error))") + } else { + log.error("Account: Failed to modify account email") + } + + self?.textEmail.text = "" + + let alert = Macros.alert(L10n.Signup.Unreachable.vcTitle, L10n.Welcome.Update.Account.Email.error) + alert.addDefaultAction(L10n.Ui.Global.close) + self?.present(alert, animated: true, completion: nil) + + return + } + + log.debug("Account: Email successfully modified") + self?.textEmail.endEditing(true) + self?.perform(segue: StoryboardSegue.Signup.successShowCredentialsSegueIdentifier) + } + + } + + private func disableInteractions() { + parent?.view.isUserInteractionEnabled = false + } + + private func enableInteractions() { + parent?.view.isUserInteractionEnabled = true + } + + override public func prepare(for segue: UIStoryboardSegue, sender: Any?) { + + guard let identifier = segue.identifier, let segueType = StoryboardSegue.Signup(rawValue: identifier) else { + return + } + switch segueType { + case .successShowCredentialsSegueIdentifier: + let vc = segue.destination as! SignupSuccessViewController + vc.metadata = metadata + vc.completionDelegate = completionDelegate + break + case .presentGDPRTermsSegue: + let gdprViewController = segue.destination as! GDPRViewController + gdprViewController.delegate = self + break + default: + break + } + + } + + private func setupAppleSignInUI() { + if #available(iOS 13.0, *) { + labelOr.text = L10n.Welcome.Purchase.or.uppercased() + labelOr.textAlignment = .center + + let signInWithAppleButton = ASAuthorizationAppleIDButton(type: .signIn, style: Theme.current.palette.appearance == .dark ? .whiteOutline : .black) + signInWithAppleButton.addTarget(self, action: #selector(handleAuthorizationAppleID), for: .touchUpInside) + + self.addEmailContainer.addSubview(signInWithAppleButton) + self.addEmailContainer.addSubview(labelOr) + + labelOr.translatesAutoresizingMaskIntoConstraints = false + signInWithAppleButton.translatesAutoresizingMaskIntoConstraints = false + + NSLayoutConstraint.activate([ + labelOr.topAnchor.constraint(equalTo: self.buttonConfirm.bottomAnchor, constant: 15), + labelOr.leftAnchor.constraint(equalTo: self.addEmailContainer.leftAnchor), + labelOr.rightAnchor.constraint(equalTo: self.addEmailContainer.rightAnchor), + labelOr.heightAnchor.constraint(equalToConstant: 15), + + signInWithAppleButton.topAnchor.constraint(equalTo: self.labelOr.bottomAnchor, constant: 15), + signInWithAppleButton.leftAnchor.constraint(equalTo: self.addEmailContainer.leftAnchor), + signInWithAppleButton.rightAnchor.constraint(equalTo: self.addEmailContainer.rightAnchor), + signInWithAppleButton.heightAnchor.constraint(equalToConstant: 50) + ]) + + } + } + + // MARK: Actions + @IBAction private func handleAuthorizationAppleID() { + if #available(iOS 13.0, *) { + let request = ASAuthorizationAppleIDProvider().createRequest() + request.requestedScopes = [.email] + + let controller = ASAuthorizationController(authorizationRequests: [request]) + + controller.delegate = self + controller.presentationContextProvider = self + + controller.performRequests() + } + } + + // MARK: Restylable + override public func viewShouldRestyle() { + super.viewShouldRestyle() + navigationItem.titleView = NavigationLogoView() + Theme.current.applyNavigationBarStyle(to: self) + Theme.current.applyPrincipalBackground(view) + Theme.current.applyInput(textEmail) + Theme.current.applyTitle(labelTitle, appearance: .dark) + Theme.current.applySubtitle(labelSubtitle) + Theme.current.applySubtitle(labelOr) + } + + private func styleConfirmButton() { + buttonConfirm.setRounded() + buttonConfirm.style(style: TextStyle.Buttons.piaGreenButton) + buttonConfirm.setTitle(L10n.Welcome.Purchase.submit.uppercased(), + for: []) + } + +} + +extension ConfirmVPNPlanViewController: GDPRDelegate { + + public func gdprViewWasAccepted() { + self.termsAndConditionsAgreed = true + self.signUp(nil) + } + + public func gdprViewWasRejected() { + self.termsAndConditionsAgreed = false + } + +} + +@available(iOS 13.0, *) +extension ConfirmVPNPlanViewController: ASAuthorizationControllerPresentationContextProviding { + public func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { + guard let appleIDCredentials = authorization.credential as? ASAuthorizationAppleIDCredential else { return } + if let email = appleIDCredentials.email { + textEmail.text = email + let preferences = Client.preferences.editable() + preferences.signInWithAppleFakeEmail = email + preferences.commit() + } else { + textEmail.text = Client.preferences.signInWithAppleFakeEmail + } + self.signUp(nil) + } +} + +@available(iOS 13.0, *) +extension ConfirmVPNPlanViewController: ASAuthorizationControllerDelegate { + public func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor { + return self.view.window! + } +} diff --git a/PIA VPN/ContentBlockerViewController.swift b/PIA VPN/ContentBlockerViewController.swift index 8159147c0..71d216076 100644 --- a/PIA VPN/ContentBlockerViewController.swift +++ b/PIA VPN/ContentBlockerViewController.swift @@ -37,13 +37,13 @@ class ContentBlockerViewController: AutolayoutViewController { override func viewDidLoad() { super.viewDidLoad() - title = L10n.ContentBlocker.title + title = L10n.Localizable.ContentBlocker.title - imvPicture.image = Asset.imageContentBlocker.image - labelTitle.text = L10n.ContentBlocker.title - labelMessage.text = L10n.ContentBlocker.Body.subtitle - labelFooter.text = L10n.ContentBlocker.Body.footer - buttonSubmit.title = L10n.Global.ok + imvPicture.image = Asset.Images.imageContentBlocker.image + labelTitle.text = L10n.Localizable.ContentBlocker.title + labelMessage.text = L10n.Localizable.ContentBlocker.Body.subtitle + labelFooter.text = L10n.Localizable.ContentBlocker.Body.footer + buttonSubmit.title = L10n.Localizable.Global.ok } @IBAction private func submit() { diff --git a/PIA VPN/CustomDNSSettingsViewController.swift b/PIA VPN/CustomDNSSettingsViewController.swift index 1066cde57..017995a55 100644 --- a/PIA VPN/CustomDNSSettingsViewController.swift +++ b/PIA VPN/CustomDNSSettingsViewController.swift @@ -22,6 +22,7 @@ import Foundation import PIALibrary +import UIKit class CustomDNSSettingsViewController: AutolayoutViewController { @@ -38,7 +39,7 @@ class CustomDNSSettingsViewController: AutolayoutViewController { override func viewDidLoad() { - self.title = L10n.Settings.Dns.Custom.dns + self.title = L10n.Localizable.Settings.Dns.Custom.dns configureTextfields() configureNavigationBar() @@ -48,7 +49,7 @@ class CustomDNSSettingsViewController: AutolayoutViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - styleNavigationBarWithTitle(L10n.Settings.Dns.Custom.dns) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Dns.Custom.dns) } // MARK: Actions @@ -72,10 +73,10 @@ class CustomDNSSettingsViewController: AutolayoutViewController { } @objc private func clear(_ sender: Any?) { - let alertController = Macros.alert(L10n.Settings.Dns.Alert.Clear.title, - L10n.Settings.Dns.Alert.Clear.message) + let alertController = Macros.alert(L10n.Localizable.Settings.Dns.Alert.Clear.title, + L10n.Localizable.Settings.Dns.Alert.Clear.message) - alertController.addActionWithTitle(L10n.Global.ok) { + alertController.addActionWithTitle(L10n.Localizable.Global.ok) { if let firstKey = DNSList.shared.firstKey() { DNSList.shared.removeServer(name: (self.vpnType == PIATunnelProfile.vpnType ? DNSList.CUSTOM_OPENVPN_DNS_KEY : DNSList.CUSTOM_WIREGUARD_DNS_KEY)) self.delegate?.updateSetting(NetworkSections.dns, @@ -83,7 +84,7 @@ class CustomDNSSettingsViewController: AutolayoutViewController { } self.navigationController?.popToRootViewController(animated: true) } - alertController.addCancelAction(L10n.Global.cancel) + alertController.addCancelAction(L10n.Localizable.Global.cancel) self.present(alertController, animated: true, @@ -95,7 +96,7 @@ class CustomDNSSettingsViewController: AutolayoutViewController { override func viewShouldRestyle() { super.viewShouldRestyle() - styleNavigationBarWithTitle(L10n.Settings.Dns.Custom.dns) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Dns.Custom.dns) if let viewContainer = viewContainer { Theme.current.applyPrincipalBackground(view) @@ -114,27 +115,27 @@ class CustomDNSSettingsViewController: AutolayoutViewController { // MARK: Private private func configureNavigationBar() { navigationItem.leftBarButtonItem = UIBarButtonItem( - title: L10n.Global.clear, + title: L10n.Localizable.Global.clear, style: .plain, target: self, action: #selector(clear(_:)) ) - navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Global.clear + navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Localizable.Global.clear navigationItem.rightBarButtonItem = UIBarButtonItem( - title: L10n.Global.update, + title: L10n.Localizable.Global.update, style: .plain, target: self, action: #selector(update(_:)) ) - navigationItem.rightBarButtonItem?.accessibilityLabel = L10n.Global.update + navigationItem.rightBarButtonItem?.accessibilityLabel = L10n.Localizable.Global.update } private func configureTextfields() { - labelPrimaryDNS.text = L10n.Settings.Dns.primaryDNS - labelSecondaryDNS.text = L10n.Settings.Dns.secondaryDNS - textPrimaryDNS.placeholder = L10n.Global.required - textSecondaryDNS.placeholder = L10n.Global.optional + labelPrimaryDNS.text = L10n.Localizable.Settings.Dns.primaryDNS + labelSecondaryDNS.text = L10n.Localizable.Settings.Dns.secondaryDNS + textPrimaryDNS.placeholder = L10n.Localizable.Global.required + textSecondaryDNS.placeholder = L10n.Localizable.Global.optional textPrimaryDNS.keyboardType = .numbersAndPunctuation textSecondaryDNS.keyboardType = .numbersAndPunctuation @@ -147,9 +148,9 @@ class CustomDNSSettingsViewController: AutolayoutViewController { if (textPrimaryDNS.text == nil || (textPrimaryDNS.text != nil && textPrimaryDNS.text!.isEmpty)) { - let alert = Macros.alert(L10n.Settings.Dns.Custom.dns, - L10n.Settings.Dns.Validation.Primary.mandatory) - alert.addDefaultAction(L10n.Global.ok) + let alert = Macros.alert(L10n.Localizable.Settings.Dns.Custom.dns, + L10n.Localizable.Settings.Dns.Validation.Primary.mandatory) + alert.addDefaultAction(L10n.Localizable.Global.ok) self.present(alert, animated: true, completion: nil) @@ -158,9 +159,9 @@ class CustomDNSSettingsViewController: AutolayoutViewController { if let primaryDNS = textPrimaryDNS.text, !isValidAddress(primaryDNS) { - let alert = Macros.alert(L10n.Settings.Dns.Custom.dns, - L10n.Settings.Dns.Validation.Primary.invalid) - alert.addDefaultAction(L10n.Global.ok) + let alert = Macros.alert(L10n.Localizable.Settings.Dns.Custom.dns, + L10n.Localizable.Settings.Dns.Validation.Primary.invalid) + alert.addDefaultAction(L10n.Localizable.Global.ok) self.present(alert, animated: true, completion: nil) @@ -170,9 +171,9 @@ class CustomDNSSettingsViewController: AutolayoutViewController { if let secondaryDNS = textSecondaryDNS.text, !secondaryDNS.isEmpty, !isValidAddress(secondaryDNS) { - let alert = Macros.alert(L10n.Settings.Dns.Custom.dns, - L10n.Settings.Dns.Validation.Secondary.invalid) - alert.addDefaultAction(L10n.Global.ok) + let alert = Macros.alert(L10n.Localizable.Settings.Dns.Custom.dns, + L10n.Localizable.Settings.Dns.Validation.Secondary.invalid) + alert.addDefaultAction(L10n.Localizable.Global.ok) self.present(alert, animated: true, completion: nil) diff --git a/PIA VPN/CustomNetworkCollectionViewCell.swift b/PIA VPN/CustomNetworkCollectionViewCell.swift index d92ced09b..f99566e49 100644 --- a/PIA VPN/CustomNetworkCollectionViewCell.swift +++ b/PIA VPN/CustomNetworkCollectionViewCell.swift @@ -60,7 +60,7 @@ class CustomNetworkCollectionViewCell: UICollectionViewCell { func viewShouldRestyle() { title.style(style: TextStyle.textStyle3) - let wifiImage = Asset.Piax.Nmt.iconNmtWifi.image.withRenderingMode(.alwaysTemplate) + let wifiImage = Asset.Images.Piax.Nmt.iconNmtWifi.image.withRenderingMode(.alwaysTemplate) wifiIcon.image = wifiImage wifiIcon.tintColor = .piaGrey4 popover.dismiss() diff --git a/PIA VPN/CustomServerSettingsViewController.swift b/PIA VPN/CustomServerSettingsViewController.swift index f4be21d4e..b9a697ad4 100644 --- a/PIA VPN/CustomServerSettingsViewController.swift +++ b/PIA VPN/CustomServerSettingsViewController.swift @@ -74,7 +74,7 @@ class CustomServerSettingsViewController: AutolayoutViewController { } else { let alertController = Macros.alert("", "You must provide a valid server information") - alertController.addCancelAction(L10n.Global.close) + alertController.addCancelAction(L10n.Localizable.Global.close) } } @@ -83,12 +83,12 @@ class CustomServerSettingsViewController: AutolayoutViewController { private func configureNavigationBar() { navigationItem.rightBarButtonItem = UIBarButtonItem( - title: L10n.Global.add, + title: L10n.Localizable.Global.add, style: .plain, target: self, action: #selector(update(_:)) ) - navigationItem.rightBarButtonItem?.accessibilityLabel = L10n.Global.add + navigationItem.rightBarButtonItem?.accessibilityLabel = L10n.Localizable.Global.add } private func configureTextfields() { diff --git a/PIA VPN/DNSList.swift b/PIA VPN/DNSList.swift index 683a976e1..717ab3393 100644 --- a/PIA VPN/DNSList.swift +++ b/PIA VPN/DNSList.swift @@ -21,6 +21,7 @@ // import Foundation +import PIALibrary class DNSList: NSObject { @@ -143,18 +144,50 @@ class DNSList: NSObject { if key == customKey { //L10n.Global.custom switch value.count { case 0: - return L10n.Settings.Dns.custom + return L10n.Localizable.Settings.Dns.custom case 1: - return L10n.Settings.Dns.custom + " (" + value.first! + ")" + return L10n.Localizable.Settings.Dns.custom + " (" + value.first! + ")" default: - return L10n.Settings.Dns.custom + " (" + value.first! + " / " + value.last! + ")" + return L10n.Localizable.Settings.Dns.custom + " (" + value.first! + " / " + value.last! + ")" } } return key } } } - return L10n.Settings.Dns.custom + return L10n.Localizable.Settings.Dns.custom + } + + /// Return if a custom DNS is set for given protocol and its configured DNS servers + func hasCustomDNS(for vpnType: String, in dnsServers: [String]) -> Bool { + guard vpnType != IKEv2Profile.vpnType && !dnsServers.isEmpty else { + return false + } + + for dns in self.dnsList { + for (_, ipsList) in dns { + if dnsServers == ipsList { + return true + } + } + } + return false + } + + /// Return if a custom DNS is set for given protocol and its configured DNS servers + func hasCustomDNS(for vpnType: String, in dnsServers: [String]) -> Bool { + guard vpnType != IKEv2Profile.vpnType && !dnsServers.isEmpty else { + return false + } + + for dns in self.dnsList { + for (_, ipsList) in dns { + if dnsServers == ipsList { + return true + } + } + } + return false } /// Updates the content of the dnsList object into the plist diff --git a/PIA VPN/DashboardViewController.swift b/PIA VPN/DashboardViewController.swift index 75d0503bb..71e0f4e22 100644 --- a/PIA VPN/DashboardViewController.swift +++ b/PIA VPN/DashboardViewController.swift @@ -25,6 +25,8 @@ import PIALibrary import SideMenu import SwiftyBeaver import WidgetKit +import NetworkExtension +import ActivityKit private let log = SwiftyBeaver.self @@ -68,7 +70,13 @@ class DashboardViewController: AutolayoutViewController { private var isDisconnecting = false private var isUnauthorized = false - private var currentStatus: VPNStatus = .disconnected + private var currentStatus: VPNStatus = .disconnected { + didSet { + if #available(iOS 16.2, *) { + startConnectionLiveActivityIfNeeded() + } + } + } private var connectingStatus: DashboardVPNConnectingStatus = .none private var tileModeStatus: TileStatus = .normal { @@ -76,6 +84,8 @@ class DashboardViewController: AutolayoutViewController { self.updateTileLayout() } } + + private var shouldReconnect = false deinit { NotificationCenter.default.removeObserver(self) @@ -117,21 +127,25 @@ class DashboardViewController: AutolayoutViewController { nc.addObserver(self, selector: #selector(checkInternetConnection), name: .PIADaemonsDidUpdateConnectivity, object: nil) nc.addObserver(self, selector: #selector(checkVPNConnectingStatus(notification:)), name: .PIADaemonsConnectingVPNStatus, object: nil) + nc.addObserver(self, selector: #selector(connectionVPNStatusDidChange(_:)), name: NSNotification.Name.NEVPNStatusDidChange, object: nil) + nc.addObserver(self, selector: #selector(handleDidConnectToRFC1918CompliantWifi(_:)), name: NSNotification.Name.DeviceDidConnectToRFC1918CompliantWifi, object: nil) + nc.addObserver(self, selector: #selector(checkConnectToRFC1918VulnerableWifi(_:)), name: NSNotification.Name.DeviceDidConnectToRFC1918VulnerableWifi, object: nil) + self.viewContentHeight = self.viewContentHeightConstraint.constant } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - + setupNavigationBarButtons() AppPreferences.shared.wasLaunched = true guard Client.providers.accountProvider.isLoggedIn else { presentLogin() - AppPreferences.shared.todayWidgetVpnStatus = L10n.Today.Widget.login - AppPreferences.shared.todayWidgetButtonTitle = L10n.Today.Widget.login + AppPreferences.shared.todayWidgetVpnStatus = L10n.Localizable.Today.Widget.login + AppPreferences.shared.todayWidgetButtonTitle = L10n.Localizable.Today.Widget.login return } @@ -143,9 +157,9 @@ class DashboardViewController: AutolayoutViewController { AppPreferences.shared.todayWidgetVpnStatus = Client.providers.vpnProvider.vpnStatus.rawValue if Client.providers.vpnProvider.vpnStatus == .disconnected { - AppPreferences.shared.todayWidgetButtonTitle = L10n.Shortcuts.connect + AppPreferences.shared.todayWidgetButtonTitle = L10n.Localizable.Shortcuts.connect } else { - AppPreferences.shared.todayWidgetButtonTitle = L10n.Shortcuts.disconnect + AppPreferences.shared.todayWidgetButtonTitle = L10n.Localizable.Shortcuts.disconnect } viewContent.isHidden = false @@ -155,6 +169,10 @@ class DashboardViewController: AutolayoutViewController { updateCurrentStatus() setupCallingCards() + // Checks if survey needs to be shown + if UserSurveyManager.shouldShowSurveyMessage() { + MessagesManager.shared.showInAppSurveyMessage() + } } override func viewDidAppear(_ animated: Bool) { @@ -236,27 +254,28 @@ class DashboardViewController: AutolayoutViewController { switch self.tileModeStatus { //change the status case .normal: if let leftBarButton = navigationItem.leftBarButtonItem, - leftBarButton.accessibilityLabel != L10n.Global.cancel { - leftBarButton.image = Asset.itemMenu.image + leftBarButton.accessibilityLabel != L10n.Localizable.Global.cancel { + leftBarButton.image = Asset.Images.itemMenu.image leftBarButton.action = #selector(openMenu(_:)) } else { navigationItem.leftBarButtonItem = UIBarButtonItem( - image: Asset.itemMenu.image, + image: Asset.Images.itemMenu.image, style: .plain, target: self, action: #selector(openMenu(_:)) ) } - navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Menu.Accessibility.item + navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Localizable.Menu.Accessibility.item + navigationItem.leftBarButtonItem?.accessibilityIdentifier = Accessibility.Id.Dashboard.menu if navigationItem.rightBarButtonItem == nil { navigationItem.rightBarButtonItem = UIBarButtonItem( - image: Asset.Piax.Global.iconEditTile.image, + image: Asset.Images.Piax.Global.iconEditTile.image, style: .plain, target: self, action: #selector(updateEditTileStatus(_:)) ) - navigationItem.rightBarButtonItem?.accessibilityLabel = L10n.Menu.Accessibility.Edit.tile + navigationItem.rightBarButtonItem?.accessibilityLabel = L10n.Localizable.Menu.Accessibility.Edit.tile } case .edit: @@ -266,7 +285,8 @@ class DashboardViewController: AutolayoutViewController { target: self, action: #selector(closeTileEditingMode(_:)) ) - navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Global.cancel + navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Localizable.Global.cancel + navigationItem.leftBarButtonItem?.accessibilityIdentifier = nil navigationItem.rightBarButtonItem = nil } @@ -307,7 +327,7 @@ class DashboardViewController: AutolayoutViewController { } if isUnauthorized { - Macros.displayImageNote(withImage: Asset.iconWarning.image, message: L10n.Account.unauthorized) + Macros.displayImageNote(withImage: Asset.Images.iconWarning.image, message: L10n.Localizable.Account.unauthorized) isUnauthorized = false } @@ -359,7 +379,8 @@ class DashboardViewController: AutolayoutViewController { } @objc private func openMenu(_ sender: Any?) { - perform(segue: StoryboardSegue.Main.menuSegueIdentifier) + Theme.current.applySideMenu() + present(SideMenuManager.default.leftMenuNavigationController!, animated: true) } @objc private func closeTileEditingMode(_ sender: Any?) { @@ -376,7 +397,6 @@ class DashboardViewController: AutolayoutViewController { } @IBAction func vpnButtonClicked(_ sender: Any?) { - if canConnectVPN() { manuallyConnect() } else { @@ -404,7 +424,7 @@ class DashboardViewController: AutolayoutViewController { guard let weakSelf = self else { return } if let _ = error { - RatingManager.shared.logError() + RatingManager.shared.handleConnectionError() } let preferences = Client.preferences.editable() @@ -428,9 +448,9 @@ class DashboardViewController: AutolayoutViewController { } func showAutomationAlert(onNMTDisableAction: (() -> ())? = nil) { - let alert = Macros.alert(nil, L10n.Network.Management.Tool.alert) - alert.addCancelAction(L10n.Global.close) - alert.addActionWithTitle(L10n.Network.Management.Tool.disable) { + let alert = Macros.alert(nil, L10n.Localizable.Network.Management.Tool.alert) + alert.addCancelAction(L10n.Localizable.Global.close) + alert.addActionWithTitle(L10n.Localizable.Network.Management.Tool.disable) { let preferences = Client.preferences.editable() preferences.nmtRulesEnabled = !Client.preferences.nmtRulesEnabled preferences.commit() @@ -487,7 +507,7 @@ class DashboardViewController: AutolayoutViewController { override func prepare(for segue: UIStoryboardSegue, sender: Any?) { navigationItem.setEmptyBackButton() - if let sideMenu = segue.destination as? UISideMenuNavigationController { + if let sideMenu = segue.destination as? SideMenuNavigationController { setMenuDelegate(menuNavigationController: sideMenu) } else if let nmt = segue.destination as? TrustedNetworksViewController { nmt.shouldReconnectAutomatically = true @@ -537,7 +557,7 @@ class DashboardViewController: AutolayoutViewController { @objc private func accountDidLogout(notification: Notification) { AppPreferences.shared.todayWidgetVpnStatus = nil - AppPreferences.shared.todayWidgetButtonTitle = L10n.Today.Widget.login + AppPreferences.shared.todayWidgetButtonTitle = L10n.Localizable.Today.Widget.login presentLogin() } @@ -558,9 +578,9 @@ class DashboardViewController: AutolayoutViewController { } @objc private func presentKillSwitchAlert() { - let alert = Macros.alert(nil, L10n.Settings.Nmt.Killswitch.disabled) - alert.addCancelAction(L10n.Global.close) - alert.addActionWithTitle(L10n.Global.enable) { + let alert = Macros.alert(nil, L10n.Localizable.Settings.Nmt.Killswitch.disabled) + alert.addCancelAction(L10n.Localizable.Global.close) + alert.addActionWithTitle(L10n.Localizable.Global.enable) { let preferences = Client.preferences.editable() preferences.isPersistentConnection = true preferences.commit() @@ -575,17 +595,17 @@ class DashboardViewController: AutolayoutViewController { if Client.providers.vpnProvider.vpnStatus != .disconnected { let alert = Macros.alert( title, - L10n.Settings.Commit.Messages.shouldReconnect + L10n.Localizable.Settings.Commit.Messages.shouldReconnect ) // reconnect -> reconnect VPN and close - alert.addActionWithTitle(L10n.Settings.Commit.Buttons.reconnect) { + alert.addActionWithTitle(L10n.Localizable.Settings.Commit.Buttons.reconnect) { Client.providers.vpnProvider.reconnect(after: nil, forceDisconnect: true, { error in }) } // later -> close - alert.addCancelActionWithTitle(L10n.Settings.Commit.Buttons.later) { + alert.addCancelActionWithTitle(L10n.Localizable.Settings.Commit.Buttons.later) { } present(alert, animated: true, completion: nil) @@ -596,12 +616,217 @@ class DashboardViewController: AutolayoutViewController { } } + @objc func connectionVPNStatusDidChange(_ notification: Notification? = nil) { + guard let connection = notification?.object as? NEVPNConnection else { return } + + switch connection.status { + case .connected: + if !Client.providers.vpnProvider.isVPNConnected { + handleNonCompliantWifiConnection() + } + case .disconnected: + + let state = UIApplication.shared.applicationState + + // Only remove the notification if the app is on the foreground + if state == .active { + removeNonCompliantWifiLocalNotification() + } + + if shouldReconnect { + Client.providers.vpnProvider.connect { _ in } + shouldReconnect = false + } + default: + break + } + } + + @objc func checkConnectToRFC1918VulnerableWifi(_ notification: Notification? = nil) { + guard Client.providers.vpnProvider.isVPNConnected else { return } + + handleNonCompliantWifiConnection() + } + + @objc func handleDidConnectToRFC1918CompliantWifi(_ notification: Notification) { + // Remove non compliant wifi notification if it was present in notification center + removeNonCompliantWifiLocalNotification() + + // Remove leak protection alert when connecting to a compliant Wi-Fi + removeLeakProtectionAlert() + } + + private func handleNonCompliantWifiConnection() { + guard WifiNetworkMonitor().isConnected() else { return } + + guard Client.preferences.currentRFC1918VulnerableWifi != nil + || WifiNetworkMonitor().checkForRFC1918Vulnerability() else { return } + + guard AppPreferences.shared.showLeakProtectionNotifications else { return } + + let currentRFC1918VulnerableWifiName = Client.preferences.currentRFC1918VulnerableWifi ?? "" + + let selectedProtocol = Client.preferences.vpnType.vpnProtocol + let isWireguardSelected = selectedProtocol == PIAWGTunnelProfile.vpnType.vpnProtocol + let isOpenVPNSelected = selectedProtocol == PIATunnelProfile.vpnType.vpnProtocol + + guard !isWireguardSelected, + !isOpenVPNSelected else { + DispatchQueue.main.async { + self.presentNonCompliantWireguardWifiAlert() + self.showNonCompliantWifiLocalNotification(currentRFC1918VulnerableWifiName: currentRFC1918VulnerableWifiName) + } + + return + } + + guard Client.preferences.allowLocalDeviceAccess + && Client.preferences.leakProtection else { return } + + DispatchQueue.main.async { + self.presentNonCompliantWifiAlert() + self.showNonCompliantWifiLocalNotification(currentRFC1918VulnerableWifiName: currentRFC1918VulnerableWifiName) + } + } + + //MARK: Non compliant Wifi alert + + private struct WifiAlertAction { + let title: String + let style: UIAlertAction.Style + let action: ((UIAlertAction) -> Void)? + } + + private func showNonCompliantWifiAlert(title: String, message: String, actions: [WifiAlertAction]) { + guard + let window = UIApplication.shared.delegate?.window, + let presentedViewController = window?.rootViewController?.presentedViewController ?? window?.rootViewController + else { return } + + if let alertController = presentedViewController as? UIAlertController, alertController.title == title { return } + + let sheet = Macros.alertController(title, message) + + for action in actions { + let alertAction = UIAlertAction(title: action.title, + style: action.style, + handler: action.action) + sheet.addAction(alertAction) + } + + presentedViewController.present(sheet, animated: true, completion: nil) + } + + private func presentNonCompliantWifiAlert() { + let title = L10n.Localizable.Dashboard.Vpn.Leakprotection.Alert.title + let message = L10n.Localizable.Dashboard.Vpn.Leakprotection.Alert.message + + var alertActions = [WifiAlertAction]() + let reconnectAction = WifiAlertAction( + title: L10n.Localizable.Dashboard.Vpn.Leakprotection.Alert.cta1, + style: .default, + action: handleDisconnectAndReconnectAction) + alertActions.append(reconnectAction) + + let learnMoreAction = WifiAlertAction( + title: L10n.Localizable.Dashboard.Vpn.Leakprotection.Alert.cta2, + style: .default, + action: handleLearnMoreAction) + alertActions.append(learnMoreAction) + + let cancelAction = WifiAlertAction( + title: L10n.Localizable.Dashboard.Vpn.Leakprotection.Alert.cta3, + style: .cancel, + action: nil) + alertActions.append(cancelAction) + + showNonCompliantWifiAlert(title: title, message: message, actions: alertActions) + } + + private func presentNonCompliantWireguardWifiAlert() { + let title = L10n.Localizable.Dashboard.Vpn.Leakprotection.Alert.title + let message = L10n.Localizable.Dashboard.Vpn.Leakprotection.Ikev2.Alert.message + + var alertActions = [WifiAlertAction]() + let reconnectAction = WifiAlertAction( + title: L10n.Localizable.Dashboard.Vpn.Leakprotection.Ikev2.Alert.cta1, + + style: .default, + action: handleSwitchProtocolAction) + alertActions.append(reconnectAction) + + let learnMoreAction = WifiAlertAction( + title: L10n.Localizable.Dashboard.Vpn.Leakprotection.Alert.cta2, + style: .default, + action: handleLearnMoreAction) + alertActions.append(learnMoreAction) + + let cancelAction = WifiAlertAction( + title: L10n.Localizable.Dashboard.Vpn.Leakprotection.Alert.cta3, + style: .cancel, + action: nil) + alertActions.append(cancelAction) + + showNonCompliantWifiAlert(title: title, message: message, actions: alertActions) + } + + private func handleDisconnectAndReconnectAction(_ action: UIAlertAction) { + Client.preferences.allowLocalDeviceAccess = false + Client.providers.vpnProvider.disconnect { _ in + self.shouldReconnect = true + } + } + + private func handleLearnMoreAction(_ action: UIAlertAction) { + let application = UIApplication.shared + let learnMoreURL = AppConstants.Web.leakProtectionURL + + if application.canOpenURL(learnMoreURL) { + application.open(learnMoreURL) + } + } + + private func handleSwitchProtocolAction(_ action: UIAlertAction) { + let editable = Client.preferences.editable() + editable.vpnType = IKEv2Profile.vpnType + let action = editable.requiredVPNAction() + editable.commit() + + Client.preferences.leakProtection = true + Client.preferences.allowLocalDeviceAccess = false + + action?.execute { _ in + self.shouldReconnect = true + } + } + + func showNonCompliantWifiLocalNotification(currentRFC1918VulnerableWifiName: String) { + // 1. Remove previous non-compliant wifi notification + removeNonCompliantWifiLocalNotification() + + // 2. Show the local notification for the current non-compliant wifi + Macros.showLocalNotificationIfNotAlreadyPresent(NotificationCategory.nonCompliantWifi, type: NotificationCategory.nonCompliantWifi, body: L10n.Localizable.LocalNotification.NonCompliantWifi.text, title: L10n.Localizable.LocalNotification.NonCompliantWifi.title(currentRFC1918VulnerableWifiName), delay: 0) + } + + private func removeNonCompliantWifiLocalNotification() { + // Remove non compliant wifi notification if it was present in notification center + Macros.removeLocalNotification(NotificationCategory.nonCompliantWifi) + } + + private func removeLeakProtectionAlert() { + guard let presentedLeakProtectionAlert = UIApplication.shared.delegate?.window??.rootViewController?.presentedViewController as? UIAlertController, + presentedLeakProtectionAlert.title == L10n.Localizable.Dashboard.Vpn.Leakprotection.Alert.title else { return } + + presentedLeakProtectionAlert.dismiss(animated: true) + } + + // MARK: Helpers @objc private func vpnDidFail() { if !isDisconnecting { isDisconnecting = true Client.providers.vpnProvider.disconnect { _ in - RatingManager.shared.logError() + RatingManager.shared.handleConnectionError() self.isDisconnecting = false self.connectingStatus = .none } @@ -644,6 +869,10 @@ class DashboardViewController: AutolayoutViewController { guard Client.providers.accountProvider.isLoggedIn else { return } + + if #available(iOS 16.2, *) { + startConnectionLiveActivityIfNeeded() + } currentStatus = Client.providers.vpnProvider.vpnStatus @@ -664,10 +893,10 @@ class DashboardViewController: AutolayoutViewController { let effectiveServer = Client.preferences.displayedServer let vpn = Client.providers.vpnProvider - titleLabelView.text = L10n.Dashboard.Vpn.connected+": "+effectiveServer.name(forStatus: vpn.vpnStatus) + titleLabelView.text = L10n.Localizable.Dashboard.Vpn.connected+": "+effectiveServer.name(forStatus: vpn.vpnStatus) setNavBarTheme(.green, with: titleLabelView) AppPreferences.shared.todayWidgetVpnStatus = VPNStatus.connected.rawValue - AppPreferences.shared.todayWidgetButtonTitle = L10n.Shortcuts.disconnect + AppPreferences.shared.todayWidgetButtonTitle = L10n.Localizable.Shortcuts.disconnect Macros.removeStickyNote() connectingStatus = .none @@ -692,11 +921,11 @@ class DashboardViewController: AutolayoutViewController { TextStyle.textStyle7) switch connectingStatus { case .pleaseWait: - titleLabelView.text = L10n.Server.Reconnection.Please.wait.uppercased() + titleLabelView.text = L10n.Localizable.Server.Reconnection.Please.wait.uppercased() case .takingTime, .stillLoading: - titleLabelView.text = L10n.Server.Reconnection.Still.connection.uppercased() + titleLabelView.text = L10n.Localizable.Server.Reconnection.Still.connection.uppercased() default: - titleLabelView.text = L10n.Dashboard.Vpn.connecting.uppercased() + titleLabelView.text = L10n.Localizable.Dashboard.Vpn.connecting.uppercased() } setNavBarTheme(.normal, with: titleLabelView) @@ -710,7 +939,7 @@ class DashboardViewController: AutolayoutViewController { titleLabelView.style(style: Theme.current.palette.appearance == .dark ? TextStyle.textStyle6 : TextStyle.textStyle7) - titleLabelView.text = L10n.Dashboard.Vpn.disconnecting.uppercased() + titleLabelView.text = L10n.Localizable.Dashboard.Vpn.disconnecting.uppercased() setNavBarTheme(.normal, with: titleLabelView) case .unknown: @@ -764,7 +993,7 @@ class DashboardViewController: AutolayoutViewController { toggleConnection.isIndeterminate = false toggleConnection.isWarning = true let titleLabelView = UILabel(frame: CGRect.zero) - titleLabelView.text = L10n.Dashboard.Vpn.disconnected+": "+L10n.Tiles.Nmt.Accessibility.trusted + titleLabelView.text = L10n.Localizable.Dashboard.Vpn.disconnected+": "+L10n.Localizable.Tiles.Nmt.Accessibility.trusted titleLabelView.adjustsFontSizeToFitWidth = true titleLabelView.style(style: TextStyle.textStyle6) toggleConnection.tintColor = UIColor.piaOrange @@ -775,7 +1004,7 @@ class DashboardViewController: AutolayoutViewController { toggleConnection.isWarning = false resetNavigationBar() AppPreferences.shared.todayWidgetVpnStatus = VPNStatus.disconnected.rawValue - AppPreferences.shared.todayWidgetButtonTitle = L10n.Shortcuts.connect + AppPreferences.shared.todayWidgetButtonTitle = L10n.Localizable.Shortcuts.connect } } // MARK: Restylable @@ -999,3 +1228,28 @@ extension DashboardViewController: UICollectionViewDelegate, UICollectionViewDat } } } + + +// MARK: Live Activities + +extension DashboardViewController { + @available(iOS 16.2, *) + private func makeLiveActivityStateForCurrentConnection() -> PIAConnectionAttributes.ContentState { + let vpnProvider = Client.providers.vpnProvider + let currentServer = Client.preferences.displayedServer + + let vpnProtocol = vpnProvider.currentVPNType.vpnProtocol + + let state = PIAConnectionAttributes.ContentState(connected: vpnProvider.isVPNConnected, regionName: currentServer.name, regionFlag: "flag-\(currentServer.country.lowercased())", vpnProtocol: vpnProtocol) + return state + } + + + @available(iOS 16.2, *) + private func startConnectionLiveActivityIfNeeded() { + guard let appDelegate = UIApplication.shared.delegate as? AppDelegate, + let liveActivityManager = appDelegate.liveActivityManager else { return } + let connState = makeLiveActivityStateForCurrentConnection() + liveActivityManager.startLiveActivity(with: connState) + } +} diff --git a/PIA VPN/DedicatedIPTitleHeaderViewCell.swift b/PIA VPN/DedicatedIPTitleHeaderViewCell.swift index 22d6551c1..d86d41333 100644 --- a/PIA VPN/DedicatedIPTitleHeaderViewCell.swift +++ b/PIA VPN/DedicatedIPTitleHeaderViewCell.swift @@ -30,7 +30,7 @@ class DedicatedIPTitleHeaderViewCell: UITableViewCell { super.awakeFromNib() titleLabel.style(style: TextStyle.textStyle9) titleLabel.font = UIFont.mediumFontWith(size: 14.0) - titleLabel.text = L10n.Dedicated.Ip.Plural.title.uppercased() + titleLabel.text = L10n.Localizable.Dedicated.Ip.Plural.title.uppercased() self.backgroundColor = .clear } diff --git a/PIA VPN/DedicatedIpEmptyHeaderViewCell.swift b/PIA VPN/DedicatedIpEmptyHeaderViewCell.swift index 1aa32a16f..0628496d3 100644 --- a/PIA VPN/DedicatedIpEmptyHeaderViewCell.swift +++ b/PIA VPN/DedicatedIpEmptyHeaderViewCell.swift @@ -23,8 +23,7 @@ import UIKit import PIALibrary protocol DedicatedIpEmptyHeaderViewCellDelegate: AnyObject { - func getTimeToRetryDIP() -> TimeInterval? - func setTimeToRetryDIP(newInterval: TimeInterval) + func handleDIPActivation(with token: String, cell: DedicatedIpEmptyHeaderViewCell) } class DedicatedIpEmptyHeaderViewCell: UITableViewCell { @@ -41,10 +40,10 @@ class DedicatedIpEmptyHeaderViewCell: UITableViewCell { override func awakeFromNib() { super.awakeFromNib() self.backgroundColor = .clear - self.title.text = L10n.Dedicated.Ip.title - self.subtitle.text = L10n.Dedicated.Ip.Activation.description - self.addTokenTextfield.accessibilityLabel = L10n.Dedicated.Ip.Token.Textfield.accessibility - self.addTokenTextfield.placeholder = L10n.Dedicated.Ip.Token.Textfield.placeholder + self.title.text = L10n.Localizable.Dedicated.Ip.title + self.subtitle.text = L10n.Localizable.Dedicated.Ip.Activation.description + self.addTokenTextfield.accessibilityLabel = L10n.Localizable.Dedicated.Ip.Token.Textfield.accessibility + self.addTokenTextfield.placeholder = L10n.Localizable.Dedicated.Ip.Token.Textfield.placeholder self.addTokenTextfield.delegate = self } @@ -66,7 +65,7 @@ class DedicatedIpEmptyHeaderViewCell: UITableViewCell { private func styleButton() { addTokenButton.setRounded() addTokenButton.style(style: TextStyle.Buttons.piaGreenButton) - addTokenButton.setTitle(L10n.Dedicated.Ip.Activate.Button.title, + addTokenButton.setTitle(L10n.Localizable.Dedicated.Ip.Activate.Button.title, for: []) } @@ -78,79 +77,15 @@ class DedicatedIpEmptyHeaderViewCell: UITableViewCell { subtitle.style(style: TextStyle.textStyle8) } - private var invalidTokenLocalisedString: String { - get { - return L10n.Dedicated.Ip.Message.Invalid.token - } - } - - private func showInvalidTokenMessage() { - Macros.displayStickyNote(withMessage: invalidTokenLocalisedString, andImage: Asset.iconWarning.image) - } - - private func displayErrorMessage(errorMessage: String?, displayDuration: Double? = nil) { - Macros.displayImageNote(withImage: Asset.iconWarning.image, message: errorMessage ?? invalidTokenLocalisedString, andDuration: displayDuration) - } - - private func handleDIPActivationError(_ error: ClientError) { - switch error { - case .unauthorized: - Client.providers.accountProvider.logout(nil) - Macros.postNotification(.PIAUnauthorized) - case .throttled(let retryAfter): - let retryAfterSeconds = Double(retryAfter) - let localisedThrottlingString = L10n.Dedicated.Ip.Message.Error.retryafter("\(Int(retryAfter))") - - self.displayErrorMessage(errorMessage: NSLocalizedString(localisedThrottlingString, comment: localisedThrottlingString), - displayDuration: retryAfterSeconds) - self.delegate?.setTimeToRetryDIP(newInterval: Date().timeIntervalSince1970 + retryAfterSeconds) - default: - self.showInvalidTokenMessage() - } - } - - private func handleDIPActivation(token: String) { - NotificationCenter.default.post(name: .DedicatedIpShowAnimation, object: nil) - Client.providers.serverProvider.activateDIPToken(token) { [weak self] (server, error) in - NotificationCenter.default.post(name: .DedicatedIpHideAnimation, object: nil) - self?.addTokenTextfield.text = "" - guard let dipServer = server else { - - guard let error = error as? ClientError else { - self?.showInvalidTokenMessage() - return - } - - self?.handleDIPActivationError(error) - return - } - switch dipServer?.dipStatus { - case .active: - Macros.displaySuccessImageNote(withImage: Asset.iconWarning.image, message: L10n.Dedicated.Ip.Message.Valid.token) - case .expired: - print(L10n.Dedicated.Ip.Message.Expired.token) // we dont show the message to the user - default: - Macros.displayStickyNote(withMessage: self?.invalidTokenLocalisedString ?? "", andImage: Asset.iconWarning.image) - } - NotificationCenter.default.post(name: .DedicatedIpReload, object: nil) - NotificationCenter.default.post(name: .PIAThemeDidChange, object: nil) + @IBAction private func activateToken() { + if let token = addTokenTextfield.text { + self.delegate?.handleDIPActivation(with: token, cell: self) } } - @IBAction private func activateToken() { - if let timeUntilNextTry = self.delegate?.getTimeToRetryDIP()?.timeSinceNow() { - displayErrorMessage(errorMessage: L10n.Dedicated.Ip.Message.Error.retryafter("\(Int(timeUntilNextTry))"), displayDuration: timeUntilNextTry) - return - } - - if let token = addTokenTextfield.text, !token.isEmpty { - handleDIPActivation(token: token) - } else { - Macros.displayStickyNote(withMessage: L10n.Dedicated.Ip.Message.Incorrect.token, - andImage: Asset.iconWarning.image) - } + func emptyTokenTextField() { + addTokenTextfield.text = "" } - } extension DedicatedIpEmptyHeaderViewCell: UITextFieldDelegate { diff --git a/PIA VPN/DedicatedIpRowViewCell.swift b/PIA VPN/DedicatedIpRowViewCell.swift index 309c04531..d87472431 100644 --- a/PIA VPN/DedicatedIpRowViewCell.swift +++ b/PIA VPN/DedicatedIpRowViewCell.swift @@ -38,7 +38,7 @@ class DedicatedIpRowViewCell: UITableViewCell, Restylable { self.server = server imvFlag.setImage(fromServer: server) - imvFlag.accessibilityLabel = L10n.Dedicated.Ip.Country.Flag.accessibility(server.name) + imvFlag.accessibilityLabel = L10n.Localizable.Dedicated.Ip.Country.Flag.accessibility(server.name) labelRegion.text = server.name if let pingAddress = server.bestAddress() { diff --git a/PIA VPN/DedicatedIpViewController.swift b/PIA VPN/DedicatedIpViewController.swift index 5d6f60a1e..60649ef1b 100644 --- a/PIA VPN/DedicatedIpViewController.swift +++ b/PIA VPN/DedicatedIpViewController.swift @@ -22,6 +22,7 @@ import Foundation import PIALibrary import SwiftyBeaver +import UIKit private let log = SwiftyBeaver.self @@ -55,7 +56,7 @@ class DedicatedIpViewController: AutolayoutViewController { override func viewDidLoad() { super.viewDidLoad() - title = L10n.Dedicated.Ip.title + title = L10n.Localizable.Dedicated.Ip.title let nc = NotificationCenter.default nc.addObserver(self, selector: #selector(viewHasRotated), name: UIDevice.orientationDidChangeNotification, object: nil) @@ -69,7 +70,7 @@ class DedicatedIpViewController: AutolayoutViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - styleNavigationBarWithTitle(L10n.Dedicated.Ip.title) + styleNavigationBarWithTitle(L10n.Localizable.Dedicated.Ip.title) } override func viewWillDisappear(_ animated: Bool) { @@ -78,7 +79,7 @@ class DedicatedIpViewController: AutolayoutViewController { } @objc private func viewHasRotated() { - styleNavigationBarWithTitle(L10n.Dedicated.Ip.title) + styleNavigationBarWithTitle(L10n.Localizable.Dedicated.Ip.title) } @objc private func reloadTableView() { @@ -112,7 +113,7 @@ class DedicatedIpViewController: AutolayoutViewController { override func viewShouldRestyle() { super.viewShouldRestyle() - styleNavigationBarWithTitle(L10n.Dedicated.Ip.title) + styleNavigationBarWithTitle(L10n.Localizable.Dedicated.Ip.title) if let viewContainer = viewContainer { Theme.current.applyPrincipalBackground(view) @@ -123,7 +124,39 @@ class DedicatedIpViewController: AutolayoutViewController { self.tableView.reloadData() } - + + // MARK: DIP Token handling + + private var invalidTokenLocalisedString: String { + get { + return L10n.Localizable.Dedicated.Ip.Message.Invalid.token + } + } + + private func showInvalidTokenMessage() { + Macros.displayStickyNote(withMessage: invalidTokenLocalisedString, andImage: Asset.Images.iconWarning.image) + } + + private func displayErrorMessage(errorMessage: String?, displayDuration: Double? = nil) { + Macros.displayImageNote(withImage: Asset.Images.iconWarning.image, message: errorMessage ?? invalidTokenLocalisedString, andDuration: displayDuration) + } + + private func handleDIPActivationError(_ error: ClientError) { + switch error { + case .unauthorized: + Client.providers.accountProvider.logout(nil) + Macros.postNotification(.PIAUnauthorized) + case .throttled(let retryAfter): + let retryAfterSeconds = Double(retryAfter) + let localisedThrottlingString = L10n.Localizable.Dedicated.Ip.Message.Error.retryafter("\(Int(retryAfter))") + + displayErrorMessage(errorMessage: NSLocalizedString(localisedThrottlingString, comment: localisedThrottlingString), + displayDuration: retryAfterSeconds) + timeToRetryDIP = Date().timeIntervalSince1970 + retryAfterSeconds + default: + showInvalidTokenMessage() + } + } } extension DedicatedIpViewController: UITableViewDelegate, UITableViewDataSource { @@ -152,12 +185,12 @@ extension DedicatedIpViewController: UITableViewDelegate, UITableViewDataSource func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { if editingStyle == .delete { - let alert = Macros.alert(nil, L10n.Dedicated.Ip.remove) - alert.addCancelActionWithTitle(L10n.Global.cancel, handler: { + let alert = Macros.alert(nil, L10n.Localizable.Dedicated.Ip.remove) + alert.addCancelActionWithTitle(L10n.Localizable.Global.cancel, handler: { self.reloadTableView() }) - alert.addActionWithTitle(L10n.Global.ok) { + alert.addActionWithTitle(L10n.Localizable.Global.ok) { self.confirmDelete(row: indexPath.row) } @@ -210,13 +243,42 @@ extension DedicatedIpViewController: UITableViewDelegate, UITableViewDataSource } extension DedicatedIpViewController: DedicatedIpEmptyHeaderViewCellDelegate { - func getTimeToRetryDIP() -> TimeInterval? { - return timeToRetryDIP - } - - func setTimeToRetryDIP(newInterval: TimeInterval) { - timeToRetryDIP = newInterval + func handleDIPActivation(with token: String, cell: DedicatedIpEmptyHeaderViewCell) { + if let timeUntilNextTry = timeToRetryDIP?.timeSinceNow() { + displayErrorMessage(errorMessage: L10n.Localizable.Dedicated.Ip.Message.Error.retryafter("\(Int(timeUntilNextTry))"), displayDuration: timeUntilNextTry) + return + } + + if token.isEmpty { + Macros.displayStickyNote(withMessage: L10n.Localizable.Dedicated.Ip.Message.Incorrect.token, + andImage: Asset.Images.iconWarning.image) + return + } + + NotificationCenter.default.post(name: .DedicatedIpShowAnimation, object: nil) + Client.providers.serverProvider.activateDIPToken(token) { [weak self] (server, error) in + NotificationCenter.default.post(name: .DedicatedIpHideAnimation, object: nil) + cell.emptyTokenTextField() + guard let dipServer = server else { + + guard let error = error as? ClientError else { + self?.showInvalidTokenMessage() + return + } + + self?.handleDIPActivationError(error) + return + } + switch dipServer?.dipStatus { + case .active: + Macros.displaySuccessImageNote(withImage: Asset.Images.iconWarning.image, message: L10n.Localizable.Dedicated.Ip.Message.Valid.token) + case .expired: + print(L10n.Localizable.Dedicated.Ip.Message.Expired.token) // we dont show the message to the user + default: + Macros.displayStickyNote(withMessage: self?.invalidTokenLocalisedString ?? "", andImage: Asset.Images.iconWarning.image) + } + NotificationCenter.default.post(name: .DedicatedIpReload, object: nil) + NotificationCenter.default.post(name: .PIAThemeDidChange, object: nil) + } } - - } diff --git a/PIA VPN/DedicatedRegionCell.swift b/PIA VPN/DedicatedRegionCell.swift index 25f063efb..fe4890900 100644 --- a/PIA VPN/DedicatedRegionCell.swift +++ b/PIA VPN/DedicatedRegionCell.swift @@ -51,7 +51,7 @@ class DedicatedRegionCell: UITableViewCell, Restylable { imvFlag.setImage(fromServer: server) labelRegion.text = server.name labelIP.text = server.wireGuardAddressesForUDP?.first?.ip ?? "" - labelDedicatedIPTitle.text = L10n.Dedicated.Ip.title.uppercased() + labelDedicatedIPTitle.text = L10n.Localizable.Dedicated.Ip.title.uppercased() iconSelected = isSelected @@ -117,10 +117,10 @@ class DedicatedRegionCell: UITableViewCell, Restylable { private func updateFavoriteImage() { self.isFavorite ? - self.favoriteImageView.image = Asset.Piax.Global.favoriteSelected.image : + self.favoriteImageView.image = Asset.Images.Piax.Global.favoriteSelected.image : Theme.current.applyFavoriteUnselectedImage(self.favoriteImageView) favoriteButton.accessibilityLabel = self.isFavorite ? - L10n.Region.Accessibility.favorite : - L10n.Region.Accessibility.unfavorite + L10n.Localizable.Region.Accessibility.favorite : + L10n.Localizable.Region.Accessibility.unfavorite } } diff --git a/PIA VPN/ExpirationCell.swift b/PIA VPN/ExpirationCell.swift index 1cfe03a1f..7a9fac549 100644 --- a/PIA VPN/ExpirationCell.swift +++ b/PIA VPN/ExpirationCell.swift @@ -33,8 +33,8 @@ class ExpirationCell: UITableViewCell, Restylable { override func awakeFromNib() { super.awakeFromNib() - labelUpgrade.text = L10n.Menu.Expiration.upgrade - imvAccessory.image = Asset.accessoryExpire.image.withRenderingMode(.alwaysTemplate) + labelUpgrade.text = L10n.Localizable.Menu.Expiration.upgrade + imvAccessory.image = Asset.Images.accessoryExpire.image.withRenderingMode(.alwaysTemplate) imvAccessory.tintColor = .white } @@ -43,14 +43,14 @@ class ExpirationCell: UITableViewCell, Restylable { let timeLeftString: String if let day = timeLeft.day, (day > 0) { - timeLeftString = L10n.Menu.Expiration.days(day) + timeLeftString = L10n.Localizable.Menu.Expiration.days(day) } else if let hour = timeLeft.hour, (hour > 0) { - timeLeftString = L10n.Menu.Expiration.hours(hour) + timeLeftString = L10n.Localizable.Menu.Expiration.hours(hour) } else { - timeLeftString = L10n.Menu.Expiration.oneHour + timeLeftString = L10n.Localizable.Menu.Expiration.oneHour } - let prefix = L10n.Menu.Expiration.expiresIn + let prefix = L10n.Localizable.Menu.Expiration.expiresIn labelWarning.text = "\(prefix) \(timeLeftString)".uppercased() } diff --git a/PIA VPN/GDPRViewController.swift b/PIA VPN/GDPRViewController.swift new file mode 100644 index 000000000..ea13fbd4d --- /dev/null +++ b/PIA VPN/GDPRViewController.swift @@ -0,0 +1,82 @@ +// +// GDPRViewController.swift +// PIALibrary-iOS +// +// Created by Jose Antonio Blaya Garcia on 08/03/2019. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import PIALibrary + +public protocol GDPRDelegate: class { + + func gdprViewWasAccepted() + + func gdprViewWasRejected() + +} + +class GDPRViewController: AutolayoutViewController { + + @IBOutlet private weak var labelCollectTitle: UILabel! + @IBOutlet private weak var labelCollectDescription: UILabel! + @IBOutlet private weak var labelUseDataDescription: UILabel! + + @IBOutlet private weak var acceptButton: PIAButton! + @IBOutlet private weak var closeButton: UIButton! + + weak var delegate: GDPRDelegate? = nil + + override func viewDidLoad() { + super.viewDidLoad() + + self.labelCollectTitle.text = L10n.Welcome.Gdpr.Collect.Data.title + self.labelCollectDescription.text = L10n.Welcome.Gdpr.Collect.Data.description + self.labelUseDataDescription.text = L10n.Welcome.Gdpr.Usage.Data.description + self.acceptButton.setTitle(L10n.Welcome.Gdpr.Accept.Button.title, for: []) + } + + // MARK: Restylable + + override func viewShouldRestyle() { + super.viewShouldRestyle() + + Theme.current.applyTitle(labelCollectTitle, appearance: .dark) + Theme.current.applySubtitle(labelCollectDescription) + Theme.current.applySubtitle(labelUseDataDescription) + + acceptButton.setRounded() + acceptButton.style(style: TextStyle.Buttons.piaGreenButton) + + } + + @IBAction func accept(_ sender: Any) { + if let delegate = delegate { + delegate.gdprViewWasAccepted() + } + dismissModal() + } + + @IBAction func reject(_ sender: Any) { + if let delegate = delegate { + delegate.gdprViewWasRejected() + } + dismissModal() + } + +} diff --git a/PIA VPN/GeneralSettingsViewController.swift b/PIA VPN/GeneralSettingsViewController.swift index d23b7e3e1..134110f00 100644 --- a/PIA VPN/GeneralSettingsViewController.swift +++ b/PIA VPN/GeneralSettingsViewController.swift @@ -37,7 +37,7 @@ class GeneralSettingsViewController: PIABaseSettingsViewController { tableView.estimatedSectionFooterHeight = 1.0 switchGeoServers.addTarget(self, action: #selector(toggleGEOServers(_:)), for: .valueChanged) - switchInAppMessages.addTarget(self, action: #selector(toggleStopInAppMessages(_:)), for: .valueChanged) + switchInAppMessages.addTarget(self, action: #selector(toggleShowServiceMessages(_:)), for: .valueChanged) tableView.delegate = self tableView.dataSource = self @@ -52,7 +52,7 @@ class GeneralSettingsViewController: PIABaseSettingsViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - styleNavigationBarWithTitle(L10n.Settings.Section.general) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Section.general) } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { @@ -60,8 +60,8 @@ class GeneralSettingsViewController: PIABaseSettingsViewController { self.tableView.reloadData() } - @objc private func toggleStopInAppMessages(_ sender: UISwitch) { - AppPreferences.shared.stopInAppMessages = sender.isOn + @objc private func toggleShowServiceMessages(_ sender: UISwitch) { + AppPreferences.shared.showServiceMessages = sender.isOn } @objc private func toggleGEOServers(_ sender: UISwitch) { @@ -81,7 +81,7 @@ class GeneralSettingsViewController: PIABaseSettingsViewController { override func viewShouldRestyle() { super.viewShouldRestyle() - styleNavigationBarWithTitle(L10n.Settings.Section.general) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Section.general) // XXX: for some reason, UITableView is not affected by appearance updates if let viewContainer = viewContainer { Theme.current.applyPrincipalBackground(view) @@ -107,7 +107,7 @@ extension GeneralSettingsViewController: UITableViewDelegate, UITableViewDataSou cell.textLabel?.numberOfLines = 0 cell.textLabel?.style(style: TextStyle.textStyle21) cell.backgroundColor = .clear - cell.textLabel?.text = L10n.Settings.Reset.footer + cell.textLabel?.text = L10n.Localizable.Settings.Reset.footer return cell } return nil @@ -129,7 +129,7 @@ extension GeneralSettingsViewController: UITableViewDelegate, UITableViewDataSou case .showServiceCommunicationMessages: cell.accessoryView = switchInAppMessages cell.selectionStyle = .none - switchInAppMessages.isOn = AppPreferences.shared.stopInAppMessages //invert the boolean as the title has change to Show messages instead of Stop messages + switchInAppMessages.isOn = AppPreferences.shared.showServiceMessages //invert the boolean as the title has change to Show messages instead of Stop messages case .showGeoRegions: cell.textLabel?.numberOfLines = 0 diff --git a/PIA VPN/GetStartedViewController.swift b/PIA VPN/GetStartedViewController.swift new file mode 100644 index 000000000..0f249b09a --- /dev/null +++ b/PIA VPN/GetStartedViewController.swift @@ -0,0 +1,692 @@ +// +// GetStartedViewController.swift +// PIALibrary-iOS +// +// Created by Jose Antonio Blaya Garcia on 26/10/2018. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import PIALibrary + +public class GetStartedViewController: PIAWelcomeViewController { + + private struct Cells { + static let plan = "PlanCell" + } + + private static let smallDeviceMaxViewHeight: CGFloat = 520 + private static let maxViewHeight: CGFloat = 500 + private static let extraViewButtonsHeight: CGFloat = 48 + private static let defaultViewHeight: CGFloat = 276 + + @IBOutlet private weak var spinner: UIActivityIndicatorView! + + @IBOutlet private weak var loginButton: PIAButton! + @IBOutlet private weak var buyButton: UIButton! + @IBOutlet private weak var subscribeNowButton: PIAButton! + @IBOutlet private weak var subscribeNowTitle: UILabel! + @IBOutlet private weak var subscribeNowDescription: UILabel! + + @IBOutlet private weak var scrollContent: UIScrollView! + @IBOutlet private weak var scrollBackground: UIImageView! + @IBOutlet private weak var viewContent: UIView! + @IBOutlet private weak var pageControl: PIAPageControl! + @IBOutlet weak var hiddenButtonsView: UIView! + + @IBOutlet private weak var textAgreement: UITextView! + @IBOutlet weak var visualEffectView: UIVisualEffectView! + + private var isFetchingProducts = true + private var isFetchingFF = true + + private var signupEmail: String? + private var signupTransaction: InAppTransaction? + private var isPurchasing = false + private var isNewFlow = false + + weak var completionDelegate: WelcomeCompletionDelegate? + + @IBOutlet private weak var buttonViewConstraintHeight: NSLayoutConstraint! + @IBOutlet private weak var hiddenButtonsConstraintHeight: NSLayoutConstraint! + + //New flow + var allNewPlans: [PurchasePlan] = [.dummy, .dummy] + + @IBOutlet private weak var containerNewFlow: UIView! + @IBOutlet private weak var walkthroughImage: UIImageView! + @IBOutlet private weak var walkthroughTitle: UILabel! + @IBOutlet private weak var walkthroughDescription: UILabel! + + @IBOutlet private weak var collectionPlans: UICollectionView! + @IBOutlet private weak var newSubscribeNowButton: PIAButton! + @IBOutlet private weak var newLoginButton: PIAButton! + @IBOutlet private weak var newTextAgreement: UITextView! + + private var buttonViewIsExpanded = false { + didSet { + self.updateButtonView() + } + } + + private lazy var allData: [WalkthroughPageView.PageData] = [ + WalkthroughPageView.PageData( + title: L10n.Signup.Walkthrough.Page._1.title, + detail: L10n.Signup.Walkthrough.Page._1.description, + image: Asset.Ui.imageWalkthrough1.image + ), + WalkthroughPageView.PageData( + title: L10n.Signup.Walkthrough.Page._2.title, + detail: L10n.Signup.Walkthrough.Page._2.description, + image: Asset.Ui.imageWalkthrough2.image + ), + WalkthroughPageView.PageData( + title: L10n.Signup.Walkthrough.Page._3.title, + detail: L10n.Signup.Walkthrough.Page._3.description, + image: Asset.Ui.imageWalkthrough3.image + ) + ] + + private var tutorialViews: [WalkthroughPageView] = [] + + private var currentPageIndex = 0 + + deinit { + NotificationCenter.default.removeObserver(self) + } + + override public var supportedInterfaceOrientations: UIInterfaceOrientationMask { + return .portrait + } + + private func setupNavigationBarButtons() { + + navigationItem.leftBarButtonItem = nil + navigationItem.rightBarButtonItem = nil + + } + + override public func viewDidLoad() { + + handleInitialStatus() + setupNavigationBarButtons() + self.containerNewFlow.isHidden = true + self.visualEffectView.isHidden = true + self.pageControl.isHidden = true + collectionPlans.isUserInteractionEnabled = false + collectionPlans.delegate = self + collectionPlans.dataSource = self + + self.walkthroughTitle.text = L10n.Signup.Walkthrough.Page._2.title + self.walkthroughDescription.text = L10n.Signup.Walkthrough.Page._2.description + "\n" + L10n.Signup.Purchase.Trials.intro + ". " + + allNewPlans = [.dummy, .dummy] + completionDelegate = self + + view.backgroundColor = UIColor.piaGrey1 + + let agreement = composeAgreementText(message: L10n.Welcome.Agreement.message("")) + + textAgreement.attributedText = Theme.current.agreementText( + withMessage: agreement, + tos: L10n.Welcome.Agreement.Message.tos, + tosUrl: Client.configuration.tosUrl, + privacy: L10n.Welcome.Agreement.Message.privacy, + privacyUrl: Client.configuration.privacyUrl + ) + newTextAgreement.attributedText = Theme.current.agreementText( + withMessage: agreement, + tos: L10n.Welcome.Agreement.Message.tos, + tosUrl: Client.configuration.tosUrl, + privacy: L10n.Welcome.Agreement.Message.privacy, + privacyUrl: Client.configuration.privacyUrl + ) + + + let nc = NotificationCenter.default + nc.addObserver(self, selector: #selector(recoverAccount), name: .PIARecoverAccount, object: nil) + nc.addObserver(self, selector: #selector(productsDidFetch(notification:)), name: .__InAppDidFetchProducts, object: nil) + nc.addObserver(self, selector: #selector(featureFlagsDidFetch(notification:)), name: .__AppDidFetchFeatureFlags, object: nil) + + self.styleButtons() + visualEffectView.clipsToBounds = true + visualEffectView.layer.cornerRadius = 15 + visualEffectView.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] + + fireTimeoutForFeatureFlags() + + super.viewDidLoad() + + } + + private func composeAgreementText(message: String) -> String { + + var agreement = message + + if isNewFlow, + let index = agreement.range(of: "\n\n", options: .backwards)?.upperBound { + agreement = String(agreement.suffix(from: index)) + } + + return agreement + } + + @objc func respondToSwipeGesture(gesture: UIGestureRecognizer) { + + if let swipeGesture = gesture as? UISwipeGestureRecognizer { + + switch swipeGesture.direction { + case UISwipeGestureRecognizer.Direction.down: + buttonViewIsExpanded = false + case UISwipeGestureRecognizer.Direction.up: + buttonViewIsExpanded = true + default: + break + } + } + + } + + override public func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + coordinator.animate(alongsideTransition: { (context) in + self.scrollToPage(self.currentPageIndex, animated: false, force: true, width: size.width) + }, completion: nil) + } + + // MARK: Actions + @IBAction func confirmPlan() { + + if let index = selectedPlanIndex { + let plan = allNewPlans[index] + self.startPurchaseProcessWithEmail("", andPlan: plan) + } + + } + + private func startPurchaseProcessWithEmail(_ email: String, + andPlan plan: PurchasePlan) { + + guard !Client.store.hasUncreditedTransactions else { + let alert = Macros.alert( + nil, + L10n.Signup.Purchase.Uncredited.Alert.message + ) + alert.addCancelAction(L10n.Signup.Purchase.Uncredited.Alert.Button.cancel) + alert.addActionWithTitle(L10n.Signup.Purchase.Uncredited.Alert.Button.recover) { + self.navigationController?.popToRootViewController(animated: true) + Macros.postNotification(.PIARecoverAccount) + } + present(alert, animated: true, completion: nil) + return + + } + + isPurchasing = true + disableInteractions(fully: true) + self.showLoadingAnimation() + + preset.accountProvider.purchase(plan: plan.plan) { (transaction, error) in + self.isPurchasing = false + self.enableInteractions() + self.hideLoadingAnimation() + + guard let transaction = transaction else { + if let error = error { + let message = error.localizedDescription + Macros.displayImageNote(withImage: Asset.Images.iconWarning.image, + message: message) + } + return + } + self.signupEmail = email + self.signupTransaction = transaction + self.perform(segue: StoryboardSegue.Welcome.signupViaPurchaseSegue) + } + + } + + + @IBAction private func scrollPage(_ sender: UIPageControl) { + scrollToPage(sender.currentPage, animated: true) + } + + public static func withPurchase(preset: Preset? = nil, delegate: PIAWelcomeViewControllerDelegate? = nil) -> UIViewController { + if let vc = StoryboardScene.Welcome.storyboard.instantiateViewController(withIdentifier: "PIAWelcomeViewController") as? PIAWelcomeViewController { + if let customPreset = preset { + vc.preset = customPreset + } + vc.delegate = delegate + let navigationController = UINavigationController(rootViewController: vc) + return navigationController + } + return UIViewController() + } + + public override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + + if (segue.identifier == StoryboardSegue.Welcome.signupViaPurchaseSegue.rawValue) { + let nav = segue.destination as! UINavigationController + let vc = nav.topViewController as! SignupInProgressViewController + + guard let email = signupEmail else { + fatalError("Signing up and signupEmail is not set") + } + var metadata = SignupMetadata(email: email) + metadata.title = L10n.Signup.InProgress.title + metadata.bodySubtitle = L10n.Signup.InProgress.message + vc.metadata = metadata + vc.signupRequest = SignupRequest(email: email, transaction: signupTransaction) + vc.preset = preset + vc.completionDelegate = completionDelegate + } + + guard let vc = segue.destination as? PIAWelcomeViewController else { + return + } + + vc.delegate = self.delegate + vc.preset = self.preset + + switch segue.identifier { + case StoryboardSegue.Welcome.purchaseVPNPlanSegue.rawValue: + vc.preset.pages = .purchase + case StoryboardSegue.Welcome.loginAccountSegue.rawValue: + vc.preset.pages = .login + case StoryboardSegue.Welcome.restorePurchaseSegue.rawValue: + vc.preset.pages = .restore + default: + break + } + + } + + public func handleInitialStatus() { + + if Client.configuration.featureFlags.contains(Client.FeatureFlags.showNewInitialScreen) { + isFetchingFF = false + isNewFlow = true + } + + if let _ = preset.accountProvider.planProducts { + isFetchingProducts = false + } + + if !isFetchingProducts && !isFetchingProducts { + self.handleVisibilityOfVIews() + } + + } + + // MARK: Orientation + @objc func onlyPortrait() -> Void {} + + // MARK: Notifications + + @objc private func productsDidFetch(notification: Notification) { + isFetchingProducts = false + let products: [Plan: InAppProduct] = notification.userInfo(for: .products) + DispatchQueue.main.async { + self.handleVisibilityOfVIews() + self.refreshPlans(products) + self.enableInteractions() + } + } + + @objc private func featureFlagsDidFetch(notification: Notification) { + isFetchingFF = false + self.isNewFlow = Client.configuration.featureFlags.contains(Client.FeatureFlags.showNewInitialScreen) + self.handleVisibilityOfVIews() + } + + private func handleVisibilityOfVIews() { + if !isFetchingFF && !isFetchingProducts { + if !isPurchasing { + self.hideLoadingAnimation() + } + + DispatchQueue.main.async { + + self.containerNewFlow.isHidden = !self.isNewFlow + self.scrollContent.isHidden = self.isNewFlow + + if self.isNewFlow { + if let products = self.preset.accountProvider.planProducts { + self.refreshPlans(products) + } + } else { + self.visualEffectView.isHidden = false + self.pageControl.isHidden = false + + let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture)) + swipeDown.direction = UISwipeGestureRecognizer.Direction.down + self.view.addGestureRecognizer(swipeDown) + + let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture)) + swipeUp.direction = UISwipeGestureRecognizer.Direction.up + self.view.addGestureRecognizer(swipeUp) + + self.subscribeNowTitle.text = L10n.Signup.Purchase.Trials.intro + } + self.addPages() + self.pageControl.numberOfPages = self.allData.count + } + + } + + } + + /// :nodoc: + public override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + setupNavigationBarButtons() + UIDevice.current.setValue(Int(UIInterfaceOrientation.portrait.rawValue), forKey: "orientation") + if let products = preset.accountProvider.planProducts { + refreshPlans(products) + } else { + showLoadingAnimation() + disableInteractions(fully: false) + } + } + + public override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + setupNavigationBarButtons() + } + + private func styleButtons() { + loginButton.setRounded() + subscribeNowButton.setRounded() + newLoginButton.setRounded() + newSubscribeNowButton.setRounded() + + subscribeNowButton.style(style: TextStyle.Buttons.piaGreenButton) + loginButton.style(style: TextStyle.Buttons.piaPlainTextButton) + newSubscribeNowButton.style(style: TextStyle.Buttons.piaGreenButton) + newLoginButton.style(style: TextStyle.Buttons.piaPlainTextButton) + + loginButton.setTitle(L10n.Welcome.Login.submit.uppercased(), + for: []) + newLoginButton.setTitle(L10n.Welcome.Login.submit.uppercased(), + for: []) + + loginButton.accessibilityIdentifier = Accessibility.Id.Login.submit + newLoginButton.accessibilityIdentifier = Accessibility.Id.Login.submitNew + + buyButton.setTitle(L10n.Signup.Purchase.Trials.All.plans, + for: []) + subscribeNowButton.setTitle(L10n.Signup.Purchase.Subscribe.now.uppercased(), + for: []) + newSubscribeNowButton.setTitle(L10n.Signup.Purchase.Subscribe.now.uppercased(), + for: []) + } + + // MARK: Helpers + + private func updateButtonView() { + UIView.animate(withDuration: 0.3, animations: { + if self.buttonViewIsExpanded { + + var maxViewHeight: CGFloat = GetStartedViewController.maxViewHeight + switch UIDevice().type { + case .iPhoneSE, .iPhone5, .iPhone5S: + maxViewHeight = GetStartedViewController.smallDeviceMaxViewHeight + default: break + } + + self.buttonViewConstraintHeight.constant = maxViewHeight + self.hiddenButtonsConstraintHeight.constant = GetStartedViewController.extraViewButtonsHeight + self.hiddenButtonsView.alpha = 1 + } else { + self.buttonViewConstraintHeight.constant = GetStartedViewController.defaultViewHeight + self.hiddenButtonsConstraintHeight.constant = 0 + self.hiddenButtonsView.alpha = 0 + } + self.view.layoutIfNeeded() + self.visualEffectView.layoutIfNeeded() + }) + } + + private func disableInteractions(fully: Bool) { + self.subscribeNowButton.isEnabled = false + self.buyButton.isEnabled = false + self.spinner.startAnimating() + } + + private func enableInteractions() { + if !isPurchasing { //dont reenable the screen if we are still purchasing + self.subscribeNowButton.isEnabled = true + self.buyButton.isEnabled = true + self.spinner.stopAnimating() + } + } + + private func fireTimeoutForFeatureFlags() { + DispatchQueue.main.asyncAfter(deadline: .now() + 5) { + // Cancel the FF request + if self.isFetchingFF { + NotificationCenter.default.removeObserver(self, name: .__AppDidFetchFeatureFlags, object: nil) + self.isFetchingFF = false + self.isNewFlow = false + self.handleVisibilityOfVIews() + } + } + } + public func navigateToLoginView() { + self.performSegue(withIdentifier: StoryboardSegue.Welcome.loginAccountSegue.rawValue, + sender: nil) + } + + // MARK: Onboarding walkthrough + + private func addPages() { + let parent = viewContent! + var constraints: [NSLayoutConstraint] = [] + var previousPage: UIView? + + for (i, data) in allData.enumerated() { + let page = WalkthroughPageView(data: data) + tutorialViews.append(page) + page.translatesAutoresizingMaskIntoConstraints = false + parent.addSubview(page) + + // size + constraints.append(page.widthAnchor.constraint(equalTo: scrollContent.widthAnchor)) + constraints.append(page.centerYAnchor.constraint(equalTo: parent.centerYAnchor)) + constraints.append(page.topAnchor.constraint(greaterThanOrEqualTo: parent.topAnchor, constant: 20.0)) + constraints.append(page.bottomAnchor.constraint(lessThanOrEqualTo: parent.bottomAnchor, constant: -20.0)) + + // left + if let previousPage = previousPage { + constraints.append(page.leftAnchor.constraint(equalTo: previousPage.rightAnchor)) + } else { + constraints.append(page.leftAnchor.constraint(equalTo: parent.leftAnchor)) + } + + // right + if (i == allData.count - 1) { + constraints.append(page.rightAnchor.constraint(equalTo: parent.rightAnchor)) + } + + previousPage = page + } + + NSLayoutConstraint.activate(constraints) + } + + private func scrollToPage(_ pageIndex: Int, animated: Bool) { + scrollToPage(pageIndex, animated: animated, force: false, width: scrollContent.frame.size.width) + } + + private func scrollToPage(_ pageIndex: Int, animated: Bool, force: Bool, width: CGFloat) { + guard (force || (pageIndex != currentPageIndex)) else { + return + } + currentPageIndex = pageIndex + scrollContent.setContentOffset(CGPoint(x: CGFloat(pageIndex * Int(width)), y: 0), animated: animated) + pageControl.currentPage = pageIndex + updateButtonsToCurrentPage() + } + + private func updateButtonsToCurrentPage() { + guard (currentPageIndex < allData.count - 1) else { + return + } + } + + + // MARK: Restylable + + /// :nodoc: + public override func viewShouldRestyle() { + super.viewShouldRestyle() + navigationItem.titleView = NavigationLogoView() + Theme.current.applyNavigationBarStyle(to: self) + + Theme.current.applyTitle(subscribeNowDescription, appearance: .light) + Theme.current.applySubtitle(subscribeNowTitle) + Theme.current.applyTitle(walkthroughTitle, appearance: .light) + Theme.current.applySubtitle(walkthroughDescription) + + Theme.current.applyTransparentButton(loginButton, + withSize: 1.0) + Theme.current.applyTransparentButton(newLoginButton, + withSize: 1.0) + Theme.current.applyButtonLabelMediumStyle(buyButton) + Theme.current.applyScrollableMap(scrollBackground) + Theme.current.applyPageControl(pageControl) + Theme.current.applyLinkAttributes(textAgreement) + Theme.current.applyLinkAttributes(newTextAgreement) + Theme.current.applyActivityIndicator(spinner) + tutorialViews.forEach({ + $0.applyStyles() + }) + + } + + // MARK: Notification event + @objc private func recoverAccount() { + self.performSegue(withIdentifier: StoryboardSegue.Welcome.restorePurchaseSegue.rawValue, + sender: nil) + } + + // MARK: InApp refresh plan + private func refreshPlans(_ plans: [Plan: InAppProduct]) { + if let yearly = plans[.yearly] { + let purchase = PurchasePlan( + plan: .yearly, + product: yearly, + monthlyFactor: 12.0 + ) + + purchase.title = L10n.Welcome.Plan.Yearly.title + let currencySymbol = purchase.product.priceLocale.currencySymbol ?? "" + purchase.detail = L10n.Welcome.Plan.Yearly.detailFormat(currencySymbol, purchase.product.price.description) + purchase.bestValue = true + let price = L10n.Welcome.Plan.Yearly.detailFormat(currencySymbol, purchase.product.price.description) + allNewPlans[0] = purchase + + DispatchQueue.main.async { [weak self] in + if let label = self?.subscribeNowDescription { + label.text = L10n.Signup.Purchase.Trials.Price.after(price) + Theme.current.makeSmallLabelToStandOut(label, + withTextToStandOut: price) + } + if let label = self?.walkthroughDescription { + label.text = L10n.Signup.Walkthrough.Page._2.description + "\n" + L10n.Signup.Purchase.Trials.intro + ". " + L10n.Signup.Purchase.Trials.Price.after(price) + Theme.current.makeSmallLabelToStandOut(label, + withTextToStandOut: price) + } + let agreement = self?.composeAgreementText(message: L10n.Welcome.Agreement.message(price)) ?? L10n.Welcome.Agreement.message(price) + if let label = self?.textAgreement { + label.attributedText = Theme.current.agreementText( + withMessage: agreement, + tos: L10n.Welcome.Agreement.Message.tos, + tosUrl: Client.configuration.tosUrl, + privacy: L10n.Welcome.Agreement.Message.privacy, + privacyUrl: Client.configuration.privacyUrl + ) + } + if let label = self?.newTextAgreement { + label.attributedText = Theme.current.agreementText( + withMessage: agreement, + tos: L10n.Welcome.Agreement.Message.tos, + tosUrl: Client.configuration.tosUrl, + privacy: L10n.Welcome.Agreement.Message.privacy, + privacyUrl: Client.configuration.privacyUrl + ) + } + } + + } + + if let monthly = plans[.monthly] { + let purchase = PurchasePlan( + plan: .monthly, + product: monthly, + monthlyFactor: 1.0 + ) + purchase.title = L10n.Welcome.Plan.Monthly.title + purchase.bestValue = false + + allNewPlans[1] = purchase + } + + collectionPlans.isUserInteractionEnabled = true + collectionPlans.reloadData() + if (selectedPlanIndex == nil) { + selectedPlanIndex = 0 + } + collectionPlans.selectItem(at: IndexPath(row: selectedPlanIndex!, section: 0), animated: false, scrollPosition: []) + + } + +} + +extension GetStartedViewController: UIScrollViewDelegate { + public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { + currentPageIndex = Int(scrollView.contentOffset.x / scrollView.bounds.size.width) + pageControl.currentPage = currentPageIndex + updateButtonsToCurrentPage() + } +} + +extension GetStartedViewController: UICollectionViewDataSource, UICollectionViewDelegate { + public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return allNewPlans.count + } + + public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let plan = allNewPlans[indexPath.row] + let cell = collectionPlans.dequeueReusableCell(withReuseIdentifier: Cells.plan, for: indexPath) as! PurchasePlanCell + cell.fill(plan: plan) + cell.isSelected = (indexPath.row == selectedPlanIndex) + return cell + } + + public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + selectedPlanIndex = indexPath.row + } +} + +extension GetStartedViewController: UICollectionViewDelegateFlowLayout { + public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + let itemWidth = collectionView.bounds.size.width + let itemHeight = (collectionView.bounds.size.height - 20) / 2.0 + return CGSize(width: itemWidth, + height: itemHeight) + } +} diff --git a/PIA VPN/IPv4Address.swift b/PIA VPN/IPv4Address.swift new file mode 100644 index 000000000..f39a032f3 --- /dev/null +++ b/PIA VPN/IPv4Address.swift @@ -0,0 +1,60 @@ +// +// IPv4Address.swift +// PIA VPN +// +// Created by Said Rehouni on 11/8/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import Network + +extension IPv4Address { + + /// https://datatracker.ietf.org/doc/html/rfc1918 + public var isRFC1918Compliant: Bool { + inRange("10.0.0.0"..."10.255.255.255") || inRange("172.16.0.0"..."172.31.255.255") + || inRange("192.168.0.0"..."192.168.255.255") + } + + /// Checks if IPAddress is in range of other address + /// - Parameter range: A range of IPAddress + /// - Returns: True if this address is within range + public func inRange(_ range: ClosedRange) -> Bool { + range.contains(self) + } +} + +extension IPv4Address: Comparable { + /// Comparison is done by converting Ipaddress to Integer + public static func < (lhs: IPv4Address, rhs: IPv4Address) -> Bool { + let lhsIntValue = representAsInteger(ipAddress: lhs) + let rhsIntValue = representAsInteger(ipAddress: rhs) + return lhsIntValue < rhsIntValue + } + + /// Converts IPAddress as integer values. Loops over each address section, shifts them and accumulate the result. + /// - Parameter ipAddress: IPAddress for conversion + /// - Returns: Integer representation + static func representAsInteger(ipAddress: IPv4Address) -> Int { + var result: Int = 0 + let octets = ipAddress.octets + for i in stride(from: 3, through: 0, by: -1) { + result += octets[3 - i] << (i * 8) + } + return result + } + + // IPAddress as an Integer array + var octets: [Int] { + return self.rawValue.map { Int($0) } + } +} + +extension IPv4Address: ExpressibleByStringLiteral { + /// Initialize from a Static String + /// Intentionally crashes when value is a bad IPaddresses + public init(stringLiteral value: StringLiteralType) { + self.init(value)! + } +} diff --git a/PIA VPN/Info.plist b/PIA VPN/Info.plist index 53cb1dce7..cbeba7e2c 100644 --- a/PIA VPN/Info.plist +++ b/PIA VPN/Info.plist @@ -51,6 +51,8 @@ We need camera access to scan a code from an gift card NSFaceIDUsageDescription Authenticate to reveal + NSSupportsLiveActivities + NSUserActivityTypes PIAConfigurationIntent diff --git a/PIA VPN/LoginViewController.swift b/PIA VPN/LoginViewController.swift new file mode 100644 index 000000000..1455943e0 --- /dev/null +++ b/PIA VPN/LoginViewController.swift @@ -0,0 +1,410 @@ +// +// LoginViewController.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/19/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import SwiftyBeaver +import PIALibrary + +private let log = SwiftyBeaver.self + +class LoginViewController: AutolayoutViewController, WelcomeChild, PIAWelcomeViewControllerDelegate { + + private enum LoginOption { + case credentials + case receipt + case magicLink + } + + @IBOutlet private weak var scrollView: UIScrollView! + + @IBOutlet private weak var labelTitle: UILabel! + + @IBOutlet private weak var textUsername: BorderedTextField! + + @IBOutlet private weak var textPassword: BorderedTextField! + + @IBOutlet private weak var buttonLogin: PIAButton! + + @IBOutlet private weak var couldNotGetPlanButton: UIButton! + + @IBOutlet private weak var loginWithReceipt: UIButton! + + @IBOutlet private weak var loginWithLink: UIButton! + + var preset: Preset? + private weak var delegate: PIAWelcomeViewControllerDelegate? + + var omitsSiblingLink = false + + weak var completionDelegate: WelcomeCompletionDelegate? + + private var signupEmail: String? + + private var isLogging = false + + private var timeToRetryCredentials: TimeInterval? = nil + private var timeToRetryReceipt: TimeInterval? = nil + private var timeToRetryMagicLink: TimeInterval? = nil + + deinit { + NotificationCenter.default.removeObserver(self) + } + + override func viewDidLoad() { + super.viewDidLoad() + + guard let preset = self.preset else { + fatalError("Preset not propagated") + } + + NotificationCenter.default.addObserver(self, selector: #selector(finishLoginWithMagicLink(notification:)), name: .PIAFinishLoginWithMagicLink, object: nil) + + labelTitle.text = L10n.Welcome.Login.title + textUsername.placeholder = L10n.Welcome.Login.Username.placeholder + textPassword.placeholder = L10n.Welcome.Login.Password.placeholder + + textUsername.accessibilityIdentifier = Accessibility.Id.Login.username + textPassword.accessibilityIdentifier = Accessibility.Id.Login.password + + textUsername.text = preset.loginUsername + textPassword.text = preset.loginPassword + + styleButtons() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + enableInteractions(true) + } + + override func didRefreshOrientationConstraints() { + scrollView.isScrollEnabled = (traitCollection.verticalSizeClass == .compact) + } + + public override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + + + guard let vc = segue.destination as? PIAWelcomeViewController else { + return + } + + vc.delegate = delegate ?? self + if let preset = preset { + vc.preset = preset + } + + switch segue.identifier { + case StoryboardSegue.Welcome.restoreLoginPurchaseSegue.rawValue: + vc.preset.pages = .restore + case StoryboardSegue.Welcome.expiredAccountPurchaseSegue.rawValue: + vc.preset.isExpired = true + vc.preset.pages = .purchase + default: + break + } + + } + // MARK: Actions + @IBAction private func logInWithLink(_ sender: Any?) { + if let timeUntilNextTry = timeToRetryMagicLink?.timeSinceNow() { + displayErrorMessage(errorMessage: L10n.Welcome.Login.Error.throttled("\(Int(timeUntilNextTry))"), displayDuration: timeUntilNextTry) + return + } + + let storyboard = UIStoryboard(name: "Welcome", bundle: Bundle.main) + if let magicLinkLoginViewController = storyboard.instantiateViewController(withIdentifier: "MagicLinkLoginViewController") as? MagicLinkLoginViewController { + let alert = Macros.alert(magicLinkLoginViewController) + alert.addCancelAction(L10n.Signup.Purchase.Uncredited.Alert.Button.cancel) + alert.addActionWithTitle(L10n.Welcome.Login.Magic.Link.send.uppercased(), handler: { + + let email = magicLinkLoginViewController.email() + guard Validator.validate(email: email) else { + Macros.displayImageNote(withImage: Asset.Images.iconWarning.image, + message: L10n.Welcome.Login.Magic.Link.Invalid.email) + return + } + + guard !self.isLogging else { + return + } + + self.showLoadingAnimation() + self.preset?.accountProvider.loginUsingMagicLink(withEmail: email, { (error) in + + self.hideLoadingAnimation() + guard error == nil else { + self.handleLoginFailed(error, loginOption: .magicLink) + return + } + + Macros.displaySuccessImageNote(withImage: Asset.Images.iconWarning.image, + message: L10n.Welcome.Login.Magic.Link.response) + }) + + }) + present(alert, animated: true, completion: nil) + } + + } + + @objc private func finishLoginWithMagicLink(notification: Notification) { + + if let userInfo = notification.userInfo, let error = userInfo[NotificationKey.error] as? Error { + displayErrorMessage(errorMessage: L10n.Welcome.Purchase.Error.Connectivity.title) + return + } + + self.completionDelegate?.welcomeDidLogin(withUser: + UserAccount(credentials: Credentials(username: "", + password: ""), + info: nil), + topViewController: self) + } + + @IBAction private func logInWithReceipt(_ sender: Any?) { + if let timeUntilNextTry = timeToRetryReceipt?.timeSinceNow() { + displayErrorMessage(errorMessage: L10n.Welcome.Login.Error.throttled("\(Int(timeUntilNextTry))"), displayDuration: timeUntilNextTry) + return + } + + guard !isLogging else { + return + } + + guard let receipt = Client.store.paymentReceipt else { + return + } + + let request = LoginReceiptRequest(receipt: receipt) + + prepareLogin() + preset?.accountProvider.login(with: request, { userAccount, error in + self.handleLoginResult(user: userAccount, error: error, loginOption: .receipt) + }) + } + + @IBAction private func logIn(_ sender: Any?) { + if let timeUntilNextTry = timeToRetryCredentials?.timeSinceNow() { + displayErrorMessage(errorMessage: L10n.Welcome.Login.Error.throttled("\(Int(timeUntilNextTry))"), displayDuration: timeUntilNextTry) + return + } + + guard !isLogging else { + return + } + + guard let credentials = getValidCredentials() else { + return + } + + let request = LoginRequest(credentials: credentials) + + prepareLogin() + preset?.accountProvider.login(with: request, { userAccount, error in + self.handleLoginResult(user: userAccount, error: error, loginOption: .credentials) + }) + } + + private func getValidCredentials() -> Credentials? { + guard let username = getValidTextFrom(textField: textUsername) else { + handleUsernameFieldInvalid() + return nil + } + + self.status = .restore(element: textUsername) + + guard let password = getValidTextFrom(textField: textPassword) else { + handleLoginFieldInvalid(textField: textPassword) + return nil + } + + self.status = .restore(element: textPassword) + self.status = .initial + + view.endEditing(false) + + return Credentials(username: username, password: password) + } + + private func getValidTextFrom(textField: UITextField) -> String? { + guard let text = textField.text?.trimmed(), !text.isEmpty else { + return nil + } + return text + } + + private func handleUsernameFieldInvalid() { + handleLoginFieldInvalid(textField: textUsername) + if textPassword.text == nil || textPassword.text!.isEmpty { + self.status = .error(element: textPassword) + } + } + + private func handleLoginFieldInvalid(textField: UITextField) { + let errorMessage = L10n.Welcome.Login.Error.validation + Macros.displayImageNote(withImage: Asset.Images.iconWarning.image, + message: errorMessage) + self.status = .error(element: textField) + } + + + private func prepareLogin() { + log.debug("Logging in...") + enableInteractions(false) + showLoadingAnimation() + } + + private func handleLoginResult(user: UserAccount?, error: Error?, loginOption: LoginOption) { + enableInteractions(true) + + hideLoadingAnimation() + + guard let user = user else { + handleLoginFailed(error, loginOption: loginOption) + return + } + + log.debug("Login succeeded!") + + self.completionDelegate?.welcomeDidLogin(withUser: user, topViewController: self) + } + + private func updateTimeToRetry(loginOption: LoginOption, retryAfterSeconds: Double) { + let retryAfterTimeStamp = Date().timeIntervalSince1970 + retryAfterSeconds + switch loginOption { + case .credentials: + timeToRetryCredentials = retryAfterTimeStamp + case .receipt: + timeToRetryReceipt = retryAfterTimeStamp + case .magicLink: + timeToRetryMagicLink = retryAfterTimeStamp + } + } + + private func handleLoginFailed(_ error: Error?, loginOption: LoginOption) { + var displayDuration: Double? + var errorMessage: String? + if let error = error { + if let clientError = error as? ClientError { + switch clientError { + case .unauthorized: + errorMessage = L10n.Welcome.Login.Error.unauthorized + + case .throttled(retryAfter: let retryAfter): + let localisedThrottlingString = L10n.Welcome.Login.Error.throttled("\(retryAfter)") + errorMessage = NSLocalizedString(localisedThrottlingString, comment: localisedThrottlingString) + + let retryAfterSeconds = Double(retryAfter) + displayDuration = retryAfterSeconds + + updateTimeToRetry(loginOption: loginOption, retryAfterSeconds: retryAfterSeconds) + + case .expired: + handleExpiredAccount() + return + default: + break + } + } + if (errorMessage == nil) { + errorMessage = error.localizedDescription + } + log.error("Failed to log in (error: \(error))") + } else { + log.error("Failed to log in") + } + displayErrorMessage(errorMessage: errorMessage, displayDuration: displayDuration) + } + + private func displayErrorMessage(errorMessage: String?, displayDuration: Double? = nil) { + + Macros.displayImageNote(withImage: Asset.Images.iconWarning.image, + message: errorMessage ?? L10n.Welcome.Login.Error.title, andDuration: displayDuration, + accessbilityIdentifier: Accessibility.Id.Login.Error.banner) + } + + private func handleExpiredAccount() { + perform(segue: StoryboardSegue.Welcome.expiredAccountPurchaseSegue, sender: self) + } + + private func enableInteractions(_ enable: Bool) { + parent?.view.isUserInteractionEnabled = enable + isLogging = !enable + } + + // MARK: Restylable + + override func viewShouldRestyle() { + super.viewShouldRestyle() + Theme.current.applyPrincipalBackground(view) + Theme.current.applyTitle(labelTitle, appearance: .dark) + Theme.current.applyInput(textUsername) + Theme.current.applyInput(textPassword) + Theme.current.applyButtonLabelMediumStyle(loginWithReceipt) + Theme.current.applyButtonLabelMediumStyle(loginWithLink) + Theme.current.applyButtonLabelMediumStyle(couldNotGetPlanButton) + } + + private func styleButtons() { + buttonLogin.setRounded() + buttonLogin.style(style: TextStyle.Buttons.piaGreenButton) + buttonLogin.setTitle(L10n.Welcome.Login.submit.uppercased(), + for: []) + buttonLogin.accessibilityIdentifier = Accessibility.Id.Login.submit + + couldNotGetPlanButton.setTitle(L10n.Welcome.Login.Restore.button, + for: []) + couldNotGetPlanButton.titleLabel?.numberOfLines = 0 + couldNotGetPlanButton.titleLabel?.textAlignment = .center + + loginWithReceipt.setTitle(L10n.Welcome.Login.Receipt.button, + for: []) + loginWithReceipt.titleLabel?.numberOfLines = 0 + loginWithReceipt.titleLabel?.textAlignment = .center + + loginWithLink.setTitle(L10n.Welcome.Login.Magic.Link.title, + for: []) + loginWithLink.titleLabel?.numberOfLines = 0 + loginWithLink.titleLabel?.textAlignment = .center + } + + func welcomeController(_ welcomeController: PIAWelcomeViewController, didSignupWith user: UserAccount, topViewController: UIViewController) { + completionDelegate?.welcomeDidSignup(withUser: user, topViewController: topViewController) + } + + func welcomeController(_ welcomeController: PIAWelcomeViewController, didLoginWith user: UserAccount, topViewController: UIViewController) { + completionDelegate?.welcomeDidLogin(withUser: user, topViewController: topViewController) + + } + +} + +extension LoginViewController: UITextFieldDelegate { + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + if (textField == textUsername) { + textPassword.becomeFirstResponder() + } else if (textField == textPassword) { + logIn(nil) + } + return true + } +} diff --git a/PIA VPN/Macros+UI.swift b/PIA VPN/Macros+UI.swift new file mode 100644 index 000000000..8e9dc07f8 --- /dev/null +++ b/PIA VPN/Macros+UI.swift @@ -0,0 +1,523 @@ +// +// Macros+UI.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/19/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import Foundation +import UIKit +import SwiftEntryKit +import PopupDialog +import PIALibrary + +extension Macros { + + private static let bannerHeight: CGFloat = 78.5 + private static let stickyNoteName: String = "sticky_note" + + /** + Creates an `UIColor` from its RGBA components. + + - Parameter r: The red component + - Parameter g: The green component + - Parameter b: The blue component + - Parameter alpha: The alpha channel component + - Returns: An `UIColor` with the provided parameters + */ + public static func color(r: UInt8, g: UInt8, b: UInt8, alpha: UInt8) -> UIColor { + return UIColor(red: CGFloat(r) / 255.0, green: CGFloat(g) / 255.0, blue: CGFloat(b) / 255.0, alpha: CGFloat(alpha) / 255.0) + } + + /** + Creates an `UIColor` from its RGBA components expressed as a 24-bit hex plus an alpha channel. + + - Parameter hex: The red, green and blue components expressed as a 24-bit number + - Parameter alpha: The alpha channel component + - Returns: An `UIColor` with the provided parameters + */ + public static func color(hex: UInt32, alpha: UInt8) -> UIColor { + let r = UInt8((hex >> 16) & 0xff) + let g = UInt8((hex >> 8) & 0xff) + let b = UInt8(hex & 0xff) + + return color(r: r, g: g, b: b, alpha: alpha) + } + + /** + Creates an `UIColor` from its RGBA components expressed as a String hex plus an alpha channel. + + - Parameter hex: The red, green and blue components expressed as a String + - Parameter alpha: The alpha channel component + - Returns: An `UIColor` with the provided parameters + */ + public static func color(hex:String, alpha: UInt8) -> UIColor { + var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() + + if (cString.hasPrefix("#")) { + cString.remove(at: cString.startIndex) + } + + if ((cString.count) != 6) { + return UIColor.gray + } + + var rgbValue:UInt64 = 0 + Scanner(string: cString).scanHexInt64(&rgbValue) + + return UIColor( + red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0, + green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0, + blue: CGFloat(rgbValue & 0x0000FF) / 255.0, + alpha: CGFloat(alpha) + ) + } + + /** + Checks iPad device. + + - Returns: `true` if the device is an iPad + */ + public static var isDevicePad: Bool { + return (UI_USER_INTERFACE_IDIOM() == .pad) + } + + /** + Checks iPhone Plus device. + + - Returns: `true` if the device is an iPhone Plus + */ + public static var isDevicePlus: Bool { + let screen = UIScreen.main + let maxEdge = max(screen.bounds.size.width, screen.bounds.size.height) + return ((screen.scale >= 3.0) && (maxEdge < 812.0)) + } + + /** + Checks big devices, typically an iPad or iPhone Plus. + + - Returns: `true` if the device is an iPad or an iPhone Plus + */ + public static var isDeviceBig: Bool { + return (isDevicePad || (UIScreen.main.scale >= 3.0)) + } + + /** + Returns a localized full version string. + + - Returns: A localized full version string built upon the input `format` + */ + public static func localizedVersionFullString() -> String? { + guard let info = Bundle.main.infoDictionary else { + return nil + } + let versionNumber = info["CFBundleShortVersionString"] as! String + let buildNumber = info[kCFBundleVersionKey as String] as! String + return L10n.Ui.Global.Version.format(versionNumber, buildNumber) + } + + /** + Returns a localized version number string. Example "3.9.0" + */ + public static func localizedVersionNumber() -> String { + guard let info = Bundle.main.infoDictionary else { + return "" + } + let versionNumber = info["CFBundleShortVersionString"] as! String + return versionNumber + } + + /** + Shortcut to create a `PopupDialog`. + + - Parameter title: The alert title + - Parameter message: The alert message + - Returns: A `PopupDialog` object + */ + public static func alert(_ title: String?, _ message: String?) -> PopupDialog { + Macros.styleAlertPopupDialog() + let popup = PopupDialog(title: title, + message: message, + buttonAlignment: .horizontal) + return popup + } + + public static func alert(_ viewController: UIViewController, completionHandler completion: (() -> Void)? = nil) -> PopupDialog { + Macros.styleAlertPopupDialog() + let popup = PopupDialog(viewController: viewController, + buttonAlignment: .horizontal, + completion: completion) + return popup + } + + /** + Shortcut to create an `UIAlertController`. + + - Parameter title: The alert title + - Parameter message: The alert message + - Returns: An `UIAlertController` object + */ + public static func alertController(_ title: String?, _ message: String?) -> UIAlertController { + return UIAlertController(title: title, message: message, preferredStyle: .alert) + } + + /** + Style a `PopupDialog` object. + */ + public static func stylePopupDialog() { + let dialogAppearance = PopupDialogDefaultView.appearance() + dialogAppearance.backgroundColor = Theme.current.palette.appearance == .dark ? UIColor.piaGrey6 : .white + dialogAppearance.messageFont = TextStyle.textStyle12.font! + dialogAppearance.messageColor = Theme.current.palette.appearance == .dark ? .white : TextStyle.textStyle12.color + + let containerAppearance = PopupDialogContainerView.appearance() + containerAppearance.cornerRadius = 0 + containerAppearance.shadowEnabled = false + + let overlayAppearance = PopupDialogOverlayView.appearance() + overlayAppearance.color = .black + overlayAppearance.blurEnabled = false + overlayAppearance.liveBlurEnabled = false + overlayAppearance.opacity = 0.5 + + let buttonAppearance = DefaultButton.appearance() + buttonAppearance.titleFont = TextStyle.textStyle21.font! + buttonAppearance.titleColor = TextStyle.textStyle21.color + buttonAppearance.buttonColor = Theme.current.palette.appearance == .dark ? UIColor.piaGrey6 : .white + buttonAppearance.separatorColor = Theme.current.palette.appearance == .dark ? UIColor.piaGrey10 : UIColor.piaGrey1 + } + + /** + Style a PopupDialog alert view object. + */ + public static func styleAlertPopupDialog() { + let dialogAppearance = PopupDialogDefaultView.appearance() + dialogAppearance.backgroundColor = Theme.current.palette.appearance == .dark ? UIColor.piaGrey6 : .white + dialogAppearance.titleFont = TextStyle.textStyle7.font! + dialogAppearance.titleColor = Theme.current.palette.appearance == .dark ? .white : TextStyle.textStyle7.color + dialogAppearance.messageFont = TextStyle.textStyle12.font! + dialogAppearance.messageColor = Theme.current.palette.appearance == .dark ? .white : TextStyle.textStyle12.color + let containerAppearance = PopupDialogContainerView.appearance() + containerAppearance.cornerRadius = 0 + containerAppearance.shadowEnabled = false + + let overlayAppearance = PopupDialogOverlayView.appearance() + overlayAppearance.color = .black + overlayAppearance.blurEnabled = false + overlayAppearance.liveBlurEnabled = false + overlayAppearance.opacity = 0.5 + + let buttonAppearance = DefaultButton.appearance() + buttonAppearance.titleFont = TextStyle.textStyle14.font! + buttonAppearance.titleColor = TextStyle.textStyle14.color + buttonAppearance.buttonColor = Theme.current.palette.appearance == .dark ? UIColor.piaGrey6 : .white + buttonAppearance.separatorColor = Theme.current.palette.appearance == .dark ? UIColor.piaGrey10 : UIColor.piaGrey1 + + let cancelButtonAppearance = CancelButton.appearance() + cancelButtonAppearance.titleFont = TextStyle.textStyle21.font! + cancelButtonAppearance.titleColor = TextStyle.textStyle21.color + cancelButtonAppearance.buttonColor = Theme.current.palette.appearance == .dark ? UIColor.piaGrey6 : .white + cancelButtonAppearance.separatorColor = Theme.current.palette.appearance == .dark ? UIColor.piaGrey10 : UIColor.piaGrey1 + + let destructiveButtonAppearance = DestructiveButton.appearance() + destructiveButtonAppearance.titleFont = TextStyle.textStyle15.font! + destructiveButtonAppearance.titleColor = TextStyle.textStyle15.color + destructiveButtonAppearance.buttonColor = Theme.current.palette.appearance == .dark ? UIColor.piaGrey6 : .white + destructiveButtonAppearance.separatorColor = Theme.current.palette.appearance == .dark ? UIColor.piaGrey10 : UIColor.piaGrey1 + + } + + + /** + Shortcut to display an `EKImageNoteMessageView`. + + - Parameter image: The note image + - Parameter message: The note message + - Parameter duration: Optional duration of the note + */ + public static func displayImageNote(withImage image: UIImage, + message: String, + andDuration duration: Double? = nil, + accessbilityIdentifier: String = "") { + + + var attributes = EKAttributes() + attributes = .topToast + attributes.hapticFeedbackType = .success + attributes.entryBackground = .color(color: EKColor(UIColor.piaRed)) + attributes.positionConstraints.size = .init(width: EKAttributes.PositionConstraints.Edge.fill, + height: EKAttributes.PositionConstraints.Edge.constant(value: bannerHeight)) + + if let duration = duration { + attributes.displayDuration = duration + } + + let labelContent = EKProperty.LabelContent(text: message, + style: .init(font: TextStyle.textStyle7.font!, + color: .white)) + let imageContent = EKProperty.ImageContent(image: image) + let contentView = EKImageNoteMessageView(with: labelContent, + imageContent: imageContent) + contentView.accessibilityIdentifier = accessbilityIdentifier + + SwiftEntryKit.display(entry: contentView, + using: attributes) + + } + + /** + Shortcut to display a success `EKImageNoteMessageView`. + + - Parameter image: The note image + - Parameter message: The note message + - Parameter duration: Optional duration of the note + */ + public static func displaySuccessImageNote(withImage image: UIImage, + message: String, + andDuration duration: Double? = nil) { + + + var attributes = EKAttributes() + attributes = .topToast + attributes.hapticFeedbackType = .success + attributes.entryBackground = .color(color: EKColor(UIColor.piaGreenDark20)) + attributes.positionConstraints.size = .init(width: EKAttributes.PositionConstraints.Edge.fill, + height: EKAttributes.PositionConstraints.Edge.constant(value: bannerHeight)) + + if let duration = duration { + attributes.displayDuration = duration + } + + let labelContent = EKProperty.LabelContent(text: message, + style: .init(font: TextStyle.textStyle7.font!, + color: .white)) + let imageContent = EKProperty.ImageContent(image: image) + let contentView = EKImageNoteMessageView(with: labelContent, + imageContent: imageContent) + + SwiftEntryKit.display(entry: contentView, + using: attributes) + + } + + /** + Shortcut to display a warning `EKImageNoteMessageView`. + + - Parameter image: The note image + - Parameter message: The note message + - Parameter duration: Optional duration of the note + */ + public static func displayWarningImageNote(withImage image: UIImage, + message: String, + andDuration duration: Double? = nil) { + + + var attributes = EKAttributes() + attributes = .topToast + attributes.hapticFeedbackType = .success + attributes.entryBackground = .color(color: EKColor(UIColor.piaOrange)) + attributes.positionConstraints.size = .init(width: EKAttributes.PositionConstraints.Edge.fill, + height: EKAttributes.PositionConstraints.Edge.constant(value: bannerHeight)) + + if let duration = duration { + attributes.displayDuration = duration + } + + let labelContent = EKProperty.LabelContent(text: message, + style: .init(font: TextStyle.textStyle7.font!, + color: .white)) + let imageContent = EKProperty.ImageContent(image: image) + let contentView = EKImageNoteMessageView(with: labelContent, + imageContent: imageContent) + + SwiftEntryKit.display(entry: contentView, + using: attributes) + + } + /** + Shortcut to display an infinite `EKImageNoteMessageView`. + + - Parameter message: The note message + - Parameter image: The note image + */ + public static func displayStickyNote(withMessage message: String, + andImage image: UIImage) { + + var attributes = EKAttributes() + attributes = .topToast + attributes.name = stickyNoteName + attributes.hapticFeedbackType = .success + attributes.entryBackground = .color(color: EKColor(UIColor.piaRed)) + attributes.positionConstraints.size = .init(width: EKAttributes.PositionConstraints.Edge.fill, + height: EKAttributes.PositionConstraints.Edge.constant(value: bannerHeight)) + attributes.displayDuration = .infinity + + let labelContent = EKProperty.LabelContent(text: message, + style: .init(font: TextStyle.textStyle7.font!, + color: .white)) + let imageContent = EKProperty.ImageContent(image: image) + let contentView = EKImageNoteMessageView(with: labelContent, + imageContent: imageContent) + SwiftEntryKit.display(entry: contentView, + using: attributes) + + } + + /** + Removes the current presented sticky note `EKImageNoteMessageView`. + */ + public static func removeStickyNote() { + if SwiftEntryKit.isCurrentlyDisplaying(entryNamed: stickyNoteName) { + SwiftEntryKit.dismiss() + } + } + + + /** + Shortcut to create an `UIAlertController` with `.actionSheet` preferred style. + + - Parameter request: The sheet title + - Parameter message: The sheet message + - Returns: An `UIAlertController` with `.actionSheet` preferred style + */ + public static func actionSheet(_ title: String?, _ message: String?) -> UIAlertController { + return UIAlertController(title: title, message: message, preferredStyle: .actionSheet) + } + +} + +/// Convenience methods for `PopupDialog`. +public extension PopupDialog { + + /// Add a PopupDialog DefaultButton with the handler action + /// - Parameter title: The button title + /// - Parameter handler: The button action + func addActionWithTitle(_ title: String, handler: @escaping () -> Void) { + let button = DefaultButton(title: title.uppercased(), dismissOnTap: true) { + handler() + } + self.addButton(button) + } + + /// Add a PopupDialog DestructiveButton with the handler action + /// - Parameter title: The button title + /// - Parameter handler: The button action + func addDestructiveActionWithTitle(_ title: String, handler: @escaping () -> Void) { + let button = DestructiveButton(title: title.uppercased(), dismissOnTap: true) { + handler() + } + button.accessibilityIdentifier = Accessibility.Id.Dialog.destructive + self.addButton(button) + } + + /// Add a PopupDialog CancelButton with the handler action + /// - Parameter title: The button title + /// - Parameter handler: The button action + func addCancelActionWithTitle(_ title: String, handler: @escaping () -> Void) { + let button = CancelButton(title: title.uppercased(), dismissOnTap: true) { + handler() + } + self.addButton(button) + } + + /// Add a PopupDialog Button with the handler action depending of the UIAlertAction given + /// - Parameter action: The UIAlertAction to convert into PopupDialog button + /// - Parameter handler: The button action + func addAction(_ action: UIAlertAction, handler: @escaping () -> Void) { + if let title = action.title { + switch action.style { + case .cancel: + let button = CancelButton(title: title.uppercased(), dismissOnTap: true) { + handler() + } + self.addButton(button) + default: + let button = DefaultButton(title: title.uppercased(), dismissOnTap: true) { + handler() + } + self.addButton(button) + } + } + } + + /// Add a PopupDialog simple CancelButton without handler and dismissing on tap + /// - Parameter title: The button title + func addCancelAction(_ title: String) { + let button = CancelButton(title: title.uppercased(), dismissOnTap: true, action: nil) + self.addButton(button) + } + + /// Add a PopupDialog simple DefaultButton without handler and dismissing on tap + /// - Parameter title: The button title + func addDefaultAction(_ title: String) { + let button = DefaultButton(title: title.uppercased(), dismissOnTap: true, action: nil) + self.addButton(button) + } + +} + +/// Convenience methods for `UIAlertController`. +public extension UIAlertController { + + /** + Adds a default action to an `UIAlertController`. + + - Parameter title: The action title + - Parameter handler: The action handler + */ + public func addDefaultAction(_ title: String, handler: @escaping () -> Void) { + let action = UIAlertAction(title: title, style: .default) { (action) in + handler() + } + addAction(action) + preferredAction = action + } + + /** + Adds a cancel action to an `UIAlertController`. + + - Parameter title: The action title + */ + public func addCancelAction(_ title: String) { + let action = UIAlertAction(title: title, style: .cancel) + addAction(action) + if (actions.count == 1) { + preferredAction = action + } + } + + /** + Adds a destructive action to an `UIAlertController`. + + - Parameter title: The action title + - Parameter handler: The action handler + */ + public func addDestructiveAction(_ title: String, handler: @escaping () -> Void) { + let action = UIAlertAction(title: title, style: .destructive) { (action) in + handler() + } + addAction(action) + preferredAction = action + } +} + +public extension String { + func trimmed() -> String { + return trimmingCharacters(in: .whitespacesAndNewlines) + } +} diff --git a/PIA VPN/MagicLinkLoginViewController.swift b/PIA VPN/MagicLinkLoginViewController.swift new file mode 100644 index 000000000..d3023c10e --- /dev/null +++ b/PIA VPN/MagicLinkLoginViewController.swift @@ -0,0 +1,45 @@ +// +// MagicLinkLoginViewController.swift +// PIALibrary +// +// Created by Jose Blaya on 03/09/2020. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// 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. + +// + +import UIKit + +class MagicLinkLoginViewController: AutolayoutViewController { + + @IBOutlet private weak var emailTextField: BorderedTextField! + + override func viewDidLoad() { + super.viewDidLoad() + emailTextField.placeholder = L10n.Welcome.Purchase.Email.placeholder + emailTextField.text = "" + emailTextField.keyboardType = .emailAddress + } + + override func viewShouldRestyle() { + super.viewShouldRestyle() + Theme.current.applyPrincipalBackground(view) + Theme.current.applyInput(emailTextField) + } + + public func email() -> String { + return emailTextField.text ?? "" + } + +} diff --git a/PIA VPN/MenuViewController.swift b/PIA VPN/MenuViewController.swift index cf3cda55f..f54d8b13e 100644 --- a/PIA VPN/MenuViewController.swift +++ b/PIA VPN/MenuViewController.swift @@ -91,29 +91,29 @@ class MenuViewController: AutolayoutViewController { ] private lazy var stringForItem: [Item: String] = [ - .selectRegion: L10n.Menu.Item.region, - .account: L10n.Menu.Item.account, - .dedicatedIp: L10n.Dedicated.Ip.title, - .settings: L10n.Menu.Item.settings, - .logout: L10n.Menu.Item.logout, - .about: L10n.Menu.Item.about, - .privacy: L10n.Menu.Item.Web.privacy, - .homepage: L10n.Menu.Item.Web.home, - .support: L10n.Menu.Item.Web.support, + .selectRegion: L10n.Localizable.Menu.Item.region, + .account: L10n.Localizable.Menu.Item.account, + .dedicatedIp: L10n.Localizable.Dedicated.Ip.title, + .settings: L10n.Localizable.Menu.Item.settings, + .logout: L10n.Localizable.Menu.Item.logout, + .about: L10n.Localizable.Menu.Item.about, + .privacy: L10n.Localizable.Menu.Item.Web.privacy, + .homepage: L10n.Localizable.Menu.Item.Web.home, + .support: L10n.Localizable.Menu.Item.Web.support, .version: Macros.localizedVersionFullString() ?? "" ] private lazy var iconForItem: [Item: ImageAsset] = [ - .selectRegion: Asset.iconRegion, - .account: Asset.iconAccount, - .dedicatedIp: Asset.iconDip, - .settings: Asset.iconSettings, - .logout: Asset.iconLogout, - .about: Asset.iconmenuAbout, - .privacy: Asset.iconmenuPrivacy, - .homepage: Asset.iconHomepage, - .support: Asset.iconContact, - .version: Asset.iconAccount + .selectRegion: Asset.Images.iconRegion, + .account: Asset.Images.iconAccount, + .dedicatedIp: Asset.Images.iconDip, + .settings: Asset.Images.iconSettings, + .logout: Asset.Images.iconLogout, + .about: Asset.Images.iconmenuAbout, + .privacy: Asset.Images.iconmenuPrivacy, + .homepage: Asset.Images.iconHomepage, + .support: Asset.Images.iconContact, + .version: Asset.Images.iconAccount ] deinit { @@ -132,7 +132,7 @@ class MenuViewController: AutolayoutViewController { modalPresentationCapturesStatusBarAppearance = true - imvAvatar.image = Asset.imageRobot.image + imvAvatar.image = Asset.Images.imageRobot.image var planDescription = "" if let currentUser = Client.providers.accountProvider.currentUser, @@ -142,17 +142,17 @@ class MenuViewController: AutolayoutViewController { switch info.plan { case .yearly: - planDescription = L10n.Account.Subscriptions.yearly + planDescription = L10n.Localizable.Account.Subscriptions.yearly case .monthly: - planDescription = L10n.Account.Subscriptions.monthly + planDescription = L10n.Localizable.Account.Subscriptions.monthly default: - planDescription = L10n.Account.Subscriptions.trial + planDescription = L10n.Localizable.Account.Subscriptions.trial } labelVersion.numberOfLines = 0 labelVersion.attributedText = Theme.current.smallTextWithColoredLink( - withMessage: planDescription + "\n" + L10n.Account.Subscriptions.Short.message, - link: L10n.Account.Subscriptions.Short.linkMessage) + withMessage: planDescription + "\n" + L10n.Localizable.Account.Subscriptions.Short.message, + link: L10n.Localizable.Account.Subscriptions.Short.linkMessage) labelVersion.isUserInteractionEnabled = true let tap = UITapGestureRecognizer(target: self, action: #selector(openManageSubscription)) labelVersion.addGestureRecognizer(tap) @@ -175,7 +175,7 @@ class MenuViewController: AutolayoutViewController { super.viewWillAppear(animated) currentUser = Client.providers.accountProvider.currentUser labelUsername.text = Client.providers.accountProvider.publicUsername ?? "" - labelUsername.accessibilityLabel = L10n.Menu.Accessibility.loggedAs(Client.providers.accountProvider.publicUsername ?? "") + labelUsername.accessibilityLabel = L10n.Localizable.Menu.Accessibility.loggedAs(Client.providers.accountProvider.publicUsername ?? "") } override func didRefreshOrientationConstraints() { @@ -258,12 +258,12 @@ class MenuViewController: AutolayoutViewController { } private func handlePlansListingError(_ error: Error?) { - let errorMessage = error?.localizedDescription ?? L10n.Menu.Renewal.Message.unavailable + let errorMessage = error?.localizedDescription ?? L10n.Localizable.Menu.Renewal.Message.unavailable let alert = Macros.alert( - L10n.Global.error, + L10n.Localizable.Global.error, errorMessage ) - alert.addDefaultAction(L10n.Global.close) + alert.addDefaultAction(L10n.Localizable.Global.close) present(alert, animated: true, completion: nil) } @@ -271,11 +271,11 @@ class MenuViewController: AutolayoutViewController { log.error("Account: Cannot renew trial account") let alert = Macros.alert( - L10n.Menu.Renewal.title, - L10n.Menu.Renewal.Message.trial + L10n.Localizable.Menu.Renewal.title, + L10n.Localizable.Menu.Renewal.Message.trial ) - alert.addCancelAction(L10n.Global.cancel) - alert.addActionWithTitle(L10n.Menu.Renewal.purchase) { + alert.addCancelAction(L10n.Localizable.Global.cancel) + alert.addActionWithTitle(L10n.Localizable.Menu.Renewal.purchase) { self.dismiss(animated: true) { self.delegate?.menu(didDetectTrialUpgrade: self) } @@ -288,11 +288,11 @@ class MenuViewController: AutolayoutViewController { // should never happen as the "Renew" button *should* only appear when the account is trial or renewable let alert = Macros.alert( - L10n.Menu.Renewal.title, - L10n.Menu.Renewal.Message.website + L10n.Localizable.Menu.Renewal.title, + L10n.Localizable.Menu.Renewal.Message.website ) - alert.addCancelAction(L10n.Global.cancel) - alert.addActionWithTitle(L10n.Menu.Renewal.renew) { + alert.addCancelAction(L10n.Localizable.Global.cancel) + alert.addActionWithTitle(L10n.Localizable.Menu.Renewal.renew) { guard UIApplication.shared.canOpenURL(AppConstants.Web.homeURL) else { return } UIApplication.shared.open(AppConstants.Web.homeURL, options: [:], completionHandler: nil) } @@ -335,8 +335,8 @@ class MenuViewController: AutolayoutViewController { log.error("IAP: Purchase failed (error: \(error)") - let alert = Macros.alert(L10n.Global.error, error.localizedDescription) - alert.addDefaultAction(L10n.Global.close) + let alert = Macros.alert(L10n.Localizable.Global.error, error.localizedDescription) + alert.addDefaultAction(L10n.Localizable.Global.close) present(alert, animated: true, completion: nil) } @@ -344,10 +344,10 @@ class MenuViewController: AutolayoutViewController { log.debug("Account: Renewal successfully completed") let alert = Macros.alert( - L10n.Renewal.Success.title, - L10n.Renewal.Success.message + L10n.Localizable.Renewal.Success.title, + L10n.Localizable.Renewal.Success.message ) - alert.addDefaultAction(L10n.Global.close) + alert.addDefaultAction(L10n.Localizable.Global.close) present(alert, animated: true, completion: nil) } @@ -359,21 +359,21 @@ class MenuViewController: AutolayoutViewController { } let alert = Macros.alert( - L10n.Global.error, - L10n.Renewal.Failure.message + L10n.Localizable.Global.error, + L10n.Localizable.Renewal.Failure.message ) - alert.addDefaultAction(L10n.Global.close) + alert.addDefaultAction(L10n.Localizable.Global.close) present(alert, animated: true, completion: nil) } private func logOut() { let sheet = Macros.alert( - L10n.Menu.Logout.title, - L10n.Menu.Logout.message + L10n.Localizable.Menu.Logout.title, + L10n.Localizable.Menu.Logout.message ) - sheet.addCancelAction(L10n.Global.cancel) - sheet.addDestructiveActionWithTitle(L10n.Menu.Logout.confirm) { + sheet.addCancelAction(L10n.Localizable.Global.cancel) + sheet.addDestructiveActionWithTitle(L10n.Localizable.Menu.Logout.confirm) { self.dismiss(animated: true) { log.debug("Account: Logging out...") DashboardViewController.instanceInNavigationStack()?.showLoadingAnimation() @@ -460,7 +460,7 @@ extension MenuViewController: UITableViewDataSource, UITableViewDelegate { cell.accessibilityIdentifier = "uitests.menu.account" case .logout: - cell.accessibilityIdentifier = "uitests.menu.logout" + cell.accessibilityIdentifier = Accessibility.Id.Menu.logout default: break diff --git a/PIA VPN/MessagesCommands.swift b/PIA VPN/MessagesCommands.swift index db8b58bb2..04ac97ffe 100644 --- a/PIA VPN/MessagesCommands.swift +++ b/PIA VPN/MessagesCommands.swift @@ -23,7 +23,8 @@ import Foundation import UIKit import PIALibrary import PIAWireguard -import TunnelKit +import TunnelKitCore +import TunnelKitOpenVPN protocol Command { func execute() @@ -157,8 +158,8 @@ class ActionCommand: Command { private func activateOpenVPN() { let preferences = Client.preferences.editable() - guard let currentVPNConfiguration = preferences.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNTunnelProvider.Configuration ?? - Client.preferences.defaults.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNTunnelProvider.Configuration else { + guard let currentVPNConfiguration = preferences.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNProvider.Configuration ?? + Client.preferences.defaults.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNProvider.Configuration else { fatalError("No default VPN custom configuration provided for PIA OpenVPN protocol") } diff --git a/PIA VPN/MessagesManager.swift b/PIA VPN/MessagesManager.swift index 7a913bcf5..e92a3c6ac 100644 --- a/PIA VPN/MessagesManager.swift +++ b/PIA VPN/MessagesManager.swift @@ -21,14 +21,16 @@ import Foundation import PIALibrary -import PIAAccount +import account +import UIKit public class MessagesManager: NSObject { public static let shared = MessagesManager() private var apiMessage: InAppMessage! private var systemMessage: InAppMessage! - + private static let surveyMessageID = "take-the-survey-message-banner" + public override init() { super.init() NotificationCenter.default.addObserver(self, selector: #selector(presentExpiringDIPRegionSystemMessage(notification:)), name: .PIADIPRegionExpiring, object: nil) @@ -38,18 +40,6 @@ public class MessagesManager: NSObject { deinit { NotificationCenter.default.removeObserver(self) } - - func refreshMessages() { - - if !AppPreferences.shared.stopInAppMessages { - Client.providers.accountProvider.inAppMessages(forAppVersion: Macros.localizedVersionNumber()) { (message, error) in - if let message = message, !message.wasDismissed() { - self.apiMessage = message - Macros.postNotification(.PIAUpdateFixedTiles) - } - } - } - } func postSystemMessage(message: InAppMessage) { self.systemMessage = message @@ -71,6 +61,10 @@ public class MessagesManager: NSObject { } func dismiss(message id: String) { + if id == MessagesManager.surveyMessageID { + AppPreferences.shared.userInteractedWithSurvey = true + } + AppPreferences.shared.dismissedMessages.append(id) if apiMessage != nil, id == apiMessage.id { apiMessage = nil @@ -119,14 +113,14 @@ extension InAppMessage { case .action: if let actions = self.settingAction { command = ActionCommand(actions) - Macros.displaySuccessImageNote(withImage: Asset.iconWarning.image, message: L10n.Inapp.Messages.Settings.updated) + Macros.displaySuccessImageNote(withImage: Asset.Images.iconWarning.image, message: L10n.Localizable.Inapp.Messages.Settings.updated) } default: break } command?.execute() - + executionCompletionHandler?() } func localisedMessage() -> String { @@ -175,7 +169,7 @@ extension MessagesManager { @objc private func presentExpiringDIPRegionSystemMessage(notification: Notification) { if let userInfo = notification.userInfo, let token = userInfo[NotificationKey.token] as? String { - let message = InAppMessage(withMessage: ["en-US": L10n.Dedicated.Ip.Message.Token.willexpire], id: token, link: ["en-US": L10n.Dedicated.Ip.Message.Token.Willexpire.link], type: .link, level: .system, actions: nil, view: nil, uri: AppConstants.Web.homeURL.absoluteString) + let message = InAppMessage(withMessage: ["en-US": L10n.Localizable.Dedicated.Ip.Message.Token.willexpire], id: token, link: ["en-US": L10n.Localizable.Dedicated.Ip.Message.Token.Willexpire.link], type: .link, level: .system, actions: nil, view: nil, uri: AppConstants.Web.homeURL.absoluteString) MessagesManager.shared.postSystemMessage(message: message) } @@ -192,11 +186,26 @@ extension MessagesManager { if relation[token] != nil && relation[token] != ip { //changes relation[token] = ip - let message = InAppMessage(withMessage: ["en-US": L10n.Dedicated.Ip.Message.Ip.updated], id: token, link: ["en-US":""], type: .none, level: .system, actions: nil, view: nil, uri: nil) + let message = InAppMessage(withMessage: ["en-US": L10n.Localizable.Dedicated.Ip.Message.Ip.updated], id: token, link: ["en-US":""], type: .none, level: .system, actions: nil, view: nil, uri: nil) MessagesManager.shared.postSystemMessage(message: message) } } AppPreferences.shared.dedicatedTokenIPReleation[token] = ip } } + + + func showInAppSurveyMessage() { + let message = InAppMessage(withMessage: ["en-US": L10n.Localizable.Account.Survey.message.appendDetailSymbol()], id: MessagesManager.surveyMessageID, link: ["en-US": L10n.Localizable.Account.Survey.messageLink.appendDetailSymbol()], type: .link, level: .api, actions: nil, view: nil, uri: AppConstants.Survey.formURL.absoluteString) { [weak self] in + self?.dismiss(message: MessagesManager.surveyMessageID) + } + MessagesManager.shared.postSystemMessage(message: message) + } +} + +private extension String { + func appendDetailSymbol() -> String { + let symbol = UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft ? "⟨ " : " ⟩" + return "\(self)\(symbol)" + } } diff --git a/PIA VPN/ModalNavigationSegue.swift b/PIA VPN/ModalNavigationSegue.swift index bc8f2e1bd..ab72dcab6 100644 --- a/PIA VPN/ModalNavigationSegue.swift +++ b/PIA VPN/ModalNavigationSegue.swift @@ -36,7 +36,7 @@ class ModalNavigationSegue: UIStoryboardSegue { target: modal, action: #selector(modal.dismissModal) ) - modal.navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Global.close + modal.navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Localizable.Global.close let nav = UINavigationController(rootViewController: modal) Theme.current.applyCustomNavigationBar(nav.navigationBar, diff --git a/PIA VPN/NavigationBar+Appearence..swift b/PIA VPN/NavigationBar+Appearence..swift new file mode 100644 index 000000000..e5b776e0d --- /dev/null +++ b/PIA VPN/NavigationBar+Appearence..swift @@ -0,0 +1,38 @@ +// +// NavigationBar+Appearence..swift +// PIA VPN +// +// Created by Said Rehouni on 8/11/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import UIKit + +extension UINavigationBar { + func setBackgroundAppearenceColor(_ color: UIColor?) { + if #available(iOS 13.0, *), color != nil { + let appearance = UINavigationBarAppearance() + appearance.configureWithOpaqueBackground() + appearance.backgroundColor = color + standardAppearance = appearance + scrollEdgeAppearance = standardAppearance + } + else { + barTintColor = color + } + } + + func setBackgroundAppearenceImage(_ image: UIImage?) { + if #available(iOS 13.0, *), image != nil { + let appearance = UINavigationBarAppearance() + appearance.configureWithOpaqueBackground() + appearance.backgroundImage = image + standardAppearance = appearance + scrollEdgeAppearance = standardAppearance + } + else { + setBackgroundImage(image, for: UIBarMetrics.default) + } + } +} diff --git a/PIA VPN/NavigationLogoView.swift b/PIA VPN/NavigationLogoView.swift new file mode 100644 index 000000000..a9d436ed9 --- /dev/null +++ b/PIA VPN/NavigationLogoView.swift @@ -0,0 +1,77 @@ +// +// NavigationLogoView.swift +// PIALibrary-iOS +// +// Created by Jose Antonio Blaya Garcia on 31/10/2018. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import Foundation +import UIKit + +public class NavigationLogoView: UIView { + private let imvLogo: UIImageView + + private struct Defaults { + static let maxWidth: CGFloat = 100 + } + + required init?(coder aDecoder: NSCoder) { + fatalError("Not implemented") + } + + override init(frame: CGRect) { + imvLogo = UIImageView(image: Theme.current.palette.logo) + super.init(frame: .zero) + + addSubview(imvLogo) + + // backgroundColor = .orange + // imvLogo.backgroundColor = .green + imvLogo.contentMode = .scaleAspectFit + } + + override public func layoutSubviews() { + super.layoutSubviews() + + // let navBar = navigationBar() + let imageLogo = imvLogo.image! + var imageSize = imageLogo.size + // if !Macros.isDevicePad { + let logoRatio: CGFloat = imageLogo.size.width / imageLogo.size.height + imageSize.width = min(imageLogo.size.width, Defaults.maxWidth) + imageSize.height = imageSize.width / logoRatio + // } + + var logoFrame: CGRect = .zero + logoFrame.origin.x = -imageSize.width / 2.0 + logoFrame.origin.y = -imageSize.height / 2.0 + logoFrame.size = imageSize + imvLogo.frame = logoFrame.integral + } + + private func navigationBar() -> UINavigationBar { + var parent = superview + while (parent != nil) { + if let navBar = parent as? UINavigationBar { + return navBar + } + parent = parent?.superview + } + fatalError("Not subview of a UINavigationBar") + } +} diff --git a/PIA VPN/NetworkCollectionViewCell.swift b/PIA VPN/NetworkCollectionViewCell.swift index 741c679a2..4dab7c107 100644 --- a/PIA VPN/NetworkCollectionViewCell.swift +++ b/PIA VPN/NetworkCollectionViewCell.swift @@ -45,68 +45,68 @@ class NetworkCollectionViewCell: UICollectionViewCell { guard let data = data else { return } switch data.type { case .openWiFi: - title.text = L10n.Network.Management.Tool.Open.wifi + title.text = L10n.Localizable.Network.Management.Tool.Open.wifi switch data.rule { case .alwaysConnect: - networkIcon.image = Asset.Piax.Nmt.iconOpenWifiConnect.image - networkIcon.accessibilityLabel = L10n.Network.Management.Tool.Open.wifi + " " + L10n.Network.Management.Tool.Always.connect + networkIcon.image = Asset.Images.Piax.Nmt.iconOpenWifiConnect.image + networkIcon.accessibilityLabel = L10n.Localizable.Network.Management.Tool.Open.wifi + " " + L10n.Localizable.Network.Management.Tool.Always.connect case .alwaysDisconnect: - networkIcon.image = Asset.Piax.Nmt.iconOpenWifiDisconnect.image - networkIcon.accessibilityLabel = L10n.Network.Management.Tool.Open.wifi + " " + L10n.Network.Management.Tool.Always.disconnect + networkIcon.image = Asset.Images.Piax.Nmt.iconOpenWifiDisconnect.image + networkIcon.accessibilityLabel = L10n.Localizable.Network.Management.Tool.Open.wifi + " " + L10n.Localizable.Network.Management.Tool.Always.disconnect case .retainState: - networkIcon.image = Asset.Piax.Nmt.iconOpenWifiRetain.image - networkIcon.accessibilityLabel = L10n.Network.Management.Tool.Open.wifi + " " + L10n.Network.Management.Tool.Retain.state + networkIcon.image = Asset.Images.Piax.Nmt.iconOpenWifiRetain.image + networkIcon.accessibilityLabel = L10n.Localizable.Network.Management.Tool.Open.wifi + " " + L10n.Localizable.Network.Management.Tool.Retain.state } case .protectedWiFi: - title.text = L10n.Network.Management.Tool.Secure.wifi + title.text = L10n.Localizable.Network.Management.Tool.Secure.wifi switch data.rule { case .alwaysConnect: - networkIcon.image = Asset.Piax.Nmt.iconSecureWifiConnect.image - networkIcon.accessibilityLabel = L10n.Network.Management.Tool.Secure.wifi + " " + L10n.Network.Management.Tool.Always.connect + networkIcon.image = Asset.Images.Piax.Nmt.iconSecureWifiConnect.image + networkIcon.accessibilityLabel = L10n.Localizable.Network.Management.Tool.Secure.wifi + " " + L10n.Localizable.Network.Management.Tool.Always.connect case .alwaysDisconnect: - networkIcon.image = Asset.Piax.Nmt.iconSecureWifiDisconnect.image - networkIcon.accessibilityLabel = L10n.Network.Management.Tool.Secure.wifi + " " + L10n.Network.Management.Tool.Always.disconnect + networkIcon.image = Asset.Images.Piax.Nmt.iconSecureWifiDisconnect.image + networkIcon.accessibilityLabel = L10n.Localizable.Network.Management.Tool.Secure.wifi + " " + L10n.Localizable.Network.Management.Tool.Always.disconnect case .retainState: - networkIcon.image = Asset.Piax.Nmt.iconSecureWifiRetain.image - networkIcon.accessibilityLabel = L10n.Network.Management.Tool.Secure.wifi + " " + L10n.Network.Management.Tool.Retain.state + networkIcon.image = Asset.Images.Piax.Nmt.iconSecureWifiRetain.image + networkIcon.accessibilityLabel = L10n.Localizable.Network.Management.Tool.Secure.wifi + " " + L10n.Localizable.Network.Management.Tool.Retain.state } case .cellular: - title.text = L10n.Network.Management.Tool.Mobile.data + title.text = L10n.Localizable.Network.Management.Tool.Mobile.data switch data.rule { case .alwaysConnect: - networkIcon.image = Asset.Piax.Nmt.iconMobileDataConnect.image - networkIcon.accessibilityLabel = L10n.Network.Management.Tool.Mobile.data + " " + L10n.Network.Management.Tool.Always.connect + networkIcon.image = Asset.Images.Piax.Nmt.iconMobileDataConnect.image + networkIcon.accessibilityLabel = L10n.Localizable.Network.Management.Tool.Mobile.data + " " + L10n.Localizable.Network.Management.Tool.Always.connect case .alwaysDisconnect: - networkIcon.image = Asset.Piax.Nmt.iconMobileDataDisconnect.image - networkIcon.accessibilityLabel = L10n.Network.Management.Tool.Mobile.data + " " + L10n.Network.Management.Tool.Always.disconnect + networkIcon.image = Asset.Images.Piax.Nmt.iconMobileDataDisconnect.image + networkIcon.accessibilityLabel = L10n.Localizable.Network.Management.Tool.Mobile.data + " " + L10n.Localizable.Network.Management.Tool.Always.disconnect case .retainState: - networkIcon.image = Asset.Piax.Nmt.iconMobileDataRetain.image - networkIcon.accessibilityLabel = L10n.Network.Management.Tool.Mobile.data + " " + L10n.Network.Management.Tool.Retain.state + networkIcon.image = Asset.Images.Piax.Nmt.iconMobileDataRetain.image + networkIcon.accessibilityLabel = L10n.Localizable.Network.Management.Tool.Mobile.data + " " + L10n.Localizable.Network.Management.Tool.Retain.state } case .trustedNetwork: title.text = data.ssid switch data.rule { case .alwaysConnect: - networkIcon.image = Asset.Piax.Nmt.iconCustomWifiConnect.image - networkIcon.accessibilityLabel = data.ssid + " " + L10n.Network.Management.Tool.Always.connect + networkIcon.image = Asset.Images.Piax.Nmt.iconCustomWifiConnect.image + networkIcon.accessibilityLabel = data.ssid + " " + L10n.Localizable.Network.Management.Tool.Always.connect case .alwaysDisconnect: - networkIcon.image = Asset.Piax.Nmt.iconCustomWifiDisconnect.image - networkIcon.accessibilityLabel = data.ssid + " " + L10n.Network.Management.Tool.Always.disconnect + networkIcon.image = Asset.Images.Piax.Nmt.iconCustomWifiDisconnect.image + networkIcon.accessibilityLabel = data.ssid + " " + L10n.Localizable.Network.Management.Tool.Always.disconnect case .retainState: - networkIcon.image = Asset.Piax.Nmt.iconCustomWifiRetain.image - networkIcon.accessibilityLabel = data.ssid + " " + L10n.Network.Management.Tool.Retain.state + networkIcon.image = Asset.Images.Piax.Nmt.iconCustomWifiRetain.image + networkIcon.accessibilityLabel = data.ssid + " " + L10n.Localizable.Network.Management.Tool.Retain.state } } switch data.rule { case .alwaysConnect: - subtitle.text = L10n.Network.Management.Tool.Always.connect + subtitle.text = L10n.Localizable.Network.Management.Tool.Always.connect statusColor.backgroundColor = UIColor.piaNMTGreen case .alwaysDisconnect: - subtitle.text = L10n.Network.Management.Tool.Always.disconnect + subtitle.text = L10n.Localizable.Network.Management.Tool.Always.disconnect statusColor.backgroundColor = UIColor.piaNMTRed case .retainState: - subtitle.text = L10n.Network.Management.Tool.Retain.state + subtitle.text = L10n.Localizable.Network.Management.Tool.Retain.state statusColor.backgroundColor = UIColor.piaNMTBlue } @@ -154,10 +154,10 @@ class NetworkCollectionViewCell: UICollectionViewCell { title.style(style: Theme.current.palette.appearance == .dark ? TextStyle.textStyleCardTitleDark : TextStyle.textStyleCardTitleLight) subtitle.style(style: TextStyle.textStyle8) - let optionsImage = Asset.Piax.Nmt.iconOptions.image.withRenderingMode(.alwaysTemplate) + let optionsImage = Asset.Images.Piax.Nmt.iconOptions.image.withRenderingMode(.alwaysTemplate) manageButton.setImage(optionsImage, for: .normal) manageButton.tintColor = Theme.current.palette.appearance == .dark ? UIColor.white : UIColor.piaGrey6 - manageButton.accessibilityLabel = L10n.Global.edit + manageButton.accessibilityLabel = L10n.Localizable.Global.edit popover.dismiss() } diff --git a/PIA VPN/NetworkFooterCollectionViewCell.swift b/PIA VPN/NetworkFooterCollectionViewCell.swift index b61a63c9e..635b3b3b4 100644 --- a/PIA VPN/NetworkFooterCollectionViewCell.swift +++ b/PIA VPN/NetworkFooterCollectionViewCell.swift @@ -32,7 +32,7 @@ class NetworkFooterCollectionViewCell: UICollectionViewCell { } func setup() { - self.addRuleButton.setTitle(L10n.Network.Management.Tool.Add.rule, for: .normal) + self.addRuleButton.setTitle(L10n.Localizable.Network.Management.Tool.Add.rule, for: .normal) viewShouldRestyle() } // MARK: Restylable @@ -40,10 +40,10 @@ class NetworkFooterCollectionViewCell: UICollectionViewCell { func viewShouldRestyle() { addRuleButton.titleLabel?.font = TextStyle.textStyle4.font addRuleButton.setTitleColor(TextStyle.textStyle4.color, for: .normal) - let optionsImage = Asset.Piax.Nmt.iconAddRule.image.withRenderingMode(.alwaysTemplate) + let optionsImage = Asset.Images.Piax.Nmt.iconAddRule.image.withRenderingMode(.alwaysTemplate) addRuleButton.setImage(optionsImage, for: .normal) addRuleButton.tintColor = TextStyle.textStyle4.color - addRuleButton.accessibilityLabel = L10n.Network.Management.Tool.Add.rule + addRuleButton.accessibilityLabel = L10n.Localizable.Network.Management.Tool.Add.rule } @IBAction private func addNewRule() { diff --git a/PIA VPN/NetworkMonitor.swift b/PIA VPN/NetworkMonitor.swift new file mode 100644 index 000000000..ecd302b38 --- /dev/null +++ b/PIA VPN/NetworkMonitor.swift @@ -0,0 +1,14 @@ +// +// NetworkMonitor.swift +// PIA VPN +// +// Created by Said Rehouni on 14/8/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import Foundation + +protocol NetworkMonitor { + func checkForRFC1918Vulnerability() -> Bool + func isConnected() -> Bool +} diff --git a/PIA VPN/NetworkRuleOptionView.swift b/PIA VPN/NetworkRuleOptionView.swift index 13f5dbe7a..55fd48214 100644 --- a/PIA VPN/NetworkRuleOptionView.swift +++ b/PIA VPN/NetworkRuleOptionView.swift @@ -73,20 +73,20 @@ extension NetworkRuleOptionView: UITableViewDelegate, UITableViewDataSource { switch indexPath.row { case NMTRules.alwaysConnect.rawValue: - cell.textLabel?.text = L10n.Network.Management.Tool.Always.connect - cell.textLabel?.accessibilityLabel = L10n.Global.Row.selection + " " + L10n.Network.Management.Tool.Always.connect - cell.accessoryView = UIImageView(image: Asset.Piax.Nmt.iconNmtConnect.image.withRenderingMode(.alwaysTemplate)) + cell.textLabel?.text = L10n.Localizable.Network.Management.Tool.Always.connect + cell.textLabel?.accessibilityLabel = L10n.Localizable.Global.Row.selection + " " + L10n.Localizable.Network.Management.Tool.Always.connect + cell.accessoryView = UIImageView(image: Asset.Images.Piax.Nmt.iconNmtConnect.image.withRenderingMode(.alwaysTemplate)) case NMTRules.alwaysDisconnect.rawValue: - cell.textLabel?.text = L10n.Network.Management.Tool.Always.disconnect - cell.textLabel?.accessibilityLabel = L10n.Global.Row.selection + " " + L10n.Network.Management.Tool.Always.disconnect - cell.accessoryView = UIImageView(image: Asset.Piax.Nmt.iconDisconnect.image.withRenderingMode(.alwaysTemplate)) + cell.textLabel?.text = L10n.Localizable.Network.Management.Tool.Always.disconnect + cell.textLabel?.accessibilityLabel = L10n.Localizable.Global.Row.selection + " " + L10n.Localizable.Network.Management.Tool.Always.disconnect + cell.accessoryView = UIImageView(image: Asset.Images.Piax.Nmt.iconDisconnect.image.withRenderingMode(.alwaysTemplate)) case NMTRules.retainState.rawValue: - cell.textLabel?.text = L10n.Network.Management.Tool.Retain.state - cell.textLabel?.accessibilityLabel = L10n.Global.Row.selection + " " + L10n.Network.Management.Tool.Retain.state - cell.accessoryView = UIImageView(image: Asset.Piax.Nmt.iconRetain.image.withRenderingMode(.alwaysTemplate)) + cell.textLabel?.text = L10n.Localizable.Network.Management.Tool.Retain.state + cell.textLabel?.accessibilityLabel = L10n.Localizable.Global.Row.selection + " " + L10n.Localizable.Network.Management.Tool.Retain.state + cell.accessoryView = UIImageView(image: Asset.Images.Piax.Nmt.iconRetain.image.withRenderingMode(.alwaysTemplate)) default: - cell.textLabel?.text = L10n.Global.remove - cell.textLabel?.accessibilityLabel = L10n.Global.Row.selection + " " + L10n.Global.remove + cell.textLabel?.text = L10n.Localizable.Global.remove + cell.textLabel?.accessibilityLabel = L10n.Localizable.Global.Row.selection + " " + L10n.Localizable.Global.remove cell.textLabel?.style(style: TextStyle.textStyle10) cell.accessoryView = nil } diff --git a/PIA VPN/NotificationCategory.swift b/PIA VPN/NotificationCategory.swift new file mode 100644 index 000000000..584634b5a --- /dev/null +++ b/PIA VPN/NotificationCategory.swift @@ -0,0 +1,55 @@ + +import Foundation +import UserNotifications +import PIALibrary + +public struct NotificationCategory { + public static let nonCompliantWifi = "NONCOMPLIANTWIFI" +} + + +// MARK: Local Notifications + +extension Macros { + + public static func showLocalNotification(_ id: String, type: String, body: String, info: [String: String] = [:], title: String? = nil, delay: Double = 0) { + + let content = UNMutableNotificationContent() + content.categoryIdentifier = type + content.body = body + if let title = title { + content.title = title + } + content.userInfo = info + + // Fire in minutes (60 seconds times ) + var trigger : UNTimeIntervalNotificationTrigger? = nil + if delay > 0 { + trigger = UNTimeIntervalNotificationTrigger(timeInterval: (delay * 60), repeats: false) + } + + // Create the request + let request = UNNotificationRequest(identifier: id, content: content, trigger: trigger) + + // Schedule the request with the system. + let notificationCenter = UNUserNotificationCenter.current() + notificationCenter.add(request) + + } + + public static func showLocalNotificationIfNotAlreadyPresent(_ id: String, type: String, body: String, info: [String: String] = [:], title: String? = nil, delay: Double = 1) { + let notificationCenter = UNUserNotificationCenter.current() + notificationCenter.getDeliveredNotifications { notifications in + // If the notification is not present in Notification Center, then show the notification + if notifications.first(where:{ $0.request.identifier == id }) == nil { + self.showLocalNotification(id, type: type, body: body, info: info, title: title, delay: delay) + } + } + } + + public static func removeLocalNotification(_ id: String) { + let notificationCenter = UNUserNotificationCenter.current() + notificationCenter.removeDeliveredNotifications(withIdentifiers: [id]) + } + +} diff --git a/PIA VPN/OptionsViewController.swift b/PIA VPN/OptionsViewController.swift new file mode 100644 index 000000000..31119a626 --- /dev/null +++ b/PIA VPN/OptionsViewController.swift @@ -0,0 +1,206 @@ +// +// OptionsViewController.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 12/8/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit + +/// Displays an `UITableView` with a list of dynamically rendered options. +public class OptionsViewController: AutolayoutViewController, UITableViewDataSource, UITableViewDelegate { + private var tableView: UITableView! + + /// The list of options. + public var options: [AnyHashable] = [] + + /// The initially selected option (optional). + public var selectedOption: AnyHashable? + + /// The tag of this controller for future reference. + public var tag = 0 + + /// The `OptionsViewControllerDelegate` for rendering and events. + public weak var delegate: OptionsViewControllerDelegate? + + // FIXME: table view "expands" on appearance + + /// :nodoc: + public override func viewDidLoad() { + let viewContainer = UIView(frame: view.bounds) + viewContainer.autoresizingMask = [.flexibleWidth, .flexibleHeight] + viewContainer.backgroundColor = .clear + view.addSubview(viewContainer) + self.viewContainer = viewContainer + + viewContainer.insetsLayoutMarginsFromSafeArea = false + + super.viewDidLoad() + + guard let bgColor = delegate?.backgroundColorForOptionsController(self) else { + return + } + viewContainer.backgroundColor = bgColor + guard let style = delegate?.tableStyleForOptionsController(self) else { + return + } + tableView = UITableView(frame: viewContainer.bounds, style: style) + tableView.backgroundColor = bgColor + tableView.dataSource = self + tableView.delegate = self + + viewContainer.addSubview(tableView) + + tableView.addConstaintsToSuperview(leadingOffset: 0, + trailingOffset: 0, + topOffset: 0, + bottomOffset: 0) + + delegate?.optionsController(self, didLoad: tableView) + + NotificationCenter.default.addObserver(self, selector: #selector(viewHasRotated), name: UIDevice.orientationDidChangeNotification, object: nil) + + viewShouldRestyle() + + } + + public func reload() { + self.tableView.reloadData() + } + + public override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + styleNavigationBarWithTitle(self.navigationController?.title ?? "") + } + + @objc private func viewHasRotated() { + styleNavigationBarWithTitle(self.navigationController?.title ?? "") + } + + // MARK: Restylable + + override public func viewShouldRestyle() { + super.viewShouldRestyle() + + styleNavigationBarWithTitle(self.navigationController?.title ?? "") + // XXX: for some reason, UITableView is not affected by appearance updates + if let viewContainer = viewContainer { + Theme.current.applySecondaryBackground(view) + Theme.current.applySecondaryBackground(viewContainer) + } + if tableView != nil { + Theme.current.applyPrincipalBackground(tableView) + Theme.current.applyDividerToSeparator(tableView) + tableView.reloadData() + } + + } + + // MARK: UITableViewDataSource + + /// :nodoc: + public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return options.count + } + + /// :nodoc: + public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = delegate?.optionsController(self, tableView: tableView, reusableCellAt: indexPath) else { + fatalError("Implement optionsController:tableView:reusableCellAt: in delegate") + } + + let option = options[indexPath.row] + var isSelected = false + if let selectedOption = selectedOption { + isSelected = (option == selectedOption) + } + delegate?.optionsController(self, renderOption: option, in: cell, at: indexPath.row, isSelected: isSelected) + + Theme.current.applySecondaryBackground(cell) + if let textLabel = cell.textLabel { + Theme.current.applySettingsCellTitle(textLabel, + appearance: .dark) + } + if let detailLabel = cell.detailTextLabel { + Theme.current.applySubtitle(detailLabel) + } + + let backgroundView = UIView() + Theme.current.applyPrincipalBackground(backgroundView) + cell.selectedBackgroundView = backgroundView + + return cell + } + + // MARK: UITableViewDelegate + + /// :nodoc: + public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let option = options[indexPath.row] + + delegate?.optionsController(self, didSelectOption: option, at: indexPath.row) + tableView.deselectRow(at: indexPath, animated: true) + } +} + +/// Handles rendering and receives events of an `OptionsViewController`. +public protocol OptionsViewControllerDelegate: class { + + /** + Sets the background color of the view controller. + */ + func backgroundColorForOptionsController(_ controller: OptionsViewController) -> UIColor + + /** + Sets the `UITableViewStyle` for the table view. + */ + func tableStyleForOptionsController(_ controller: OptionsViewController) -> UITableView.Style + + /** + Called after loading the embedded `UITableView`. + + - Parameter tableView: The loaded `UITableView`. + */ + func optionsController(_ controller: OptionsViewController, didLoad tableView: UITableView) + + /** + Returns a reusable `UITableViewCell` for displaying the options. + + - Parameter tableView: The parent `UITableView`. + - Parameter indexPath: The `IndexPath` for caching purposes. + */ + func optionsController(_ controller: OptionsViewController, tableView: UITableView, reusableCellAt indexPath: IndexPath) -> UITableViewCell + + /** + Renders an option in a reusable `UITableViewCell` as returned by `optionsController(_:tableView:reusableCellAt:)`. + + - Parameter option: The generic option to render. + - Parameter cell: The `UITableViewCell` in which to render the option. + - Parameter row: The row the option is in. + - Parameter isSelected: If `true`, the option is to be rendered selected. + */ + func optionsController(_ controller: OptionsViewController, renderOption option: AnyHashable, in cell: UITableViewCell, at row: Int, isSelected: Bool) + + /** + Called when an option is selected. + + - Parameter option: The selected option. + - Parameter row: The row the option is in. + */ + func optionsController(_ controller: OptionsViewController, didSelectOption option: AnyHashable, at row: Int) +} diff --git a/PIA VPN/PIACardsViewController.swift b/PIA VPN/PIACardsViewController.swift index 0583fd23a..f265e1cd1 100644 --- a/PIA VPN/PIACardsViewController.swift +++ b/PIA VPN/PIACardsViewController.swift @@ -49,7 +49,7 @@ class PIACardsViewController: UIViewController { func createSlides() -> [PIACard] { - let closeImage = Asset.iconClose.image.withRenderingMode(.alwaysTemplate) + let closeImage = Asset.Images.iconClose.image.withRenderingMode(.alwaysTemplate) var collectingCards = [PIACard]() for card in cards { @@ -72,8 +72,8 @@ class PIACardsViewController: UIViewController { } if card.hasSecondCTA() { slide.cardSecondaryCTAButton.isHidden = false - slide.cardSecondaryCTAButton.setTitle(L10n.Card.Wireguard.Cta.learn, for: []) - slide.cardSecondaryCTAButton.accessibilityIdentifier = L10n.Card.Wireguard.Cta.learn + slide.cardSecondaryCTAButton.setTitle(L10n.Localizable.Card.Wireguard.Cta.learn, for: []) + slide.cardSecondaryCTAButton.accessibilityIdentifier = L10n.Localizable.Card.Wireguard.Cta.learn slide.cardSecondaryCTAButton.addAction(for: .touchUpInside) { (button) in if let url = card.learnMoreLink { if UIApplication.shared.canOpenURL(url) { diff --git a/PIA VPN/PIAConnectionButton.swift b/PIA VPN/PIAConnectionButton.swift index 8030960e9..94bd902fb 100644 --- a/PIA VPN/PIAConnectionButton.swift +++ b/PIA VPN/PIAConnectionButton.swift @@ -45,9 +45,9 @@ class PIAConnectionButton: UIButton, Restylable { var isOn: Bool = false { didSet { if isOn == true { - self.accessibilityLabel = L10n.Dashboard.Accessibility.Vpn.Button.isOn + self.accessibilityLabel = L10n.Localizable.Dashboard.Accessibility.Vpn.Button.isOn } else { - self.accessibilityLabel = L10n.Dashboard.Accessibility.Vpn.Button.isOff + self.accessibilityLabel = L10n.Localizable.Dashboard.Accessibility.Vpn.Button.isOff } } } @@ -68,6 +68,7 @@ class PIAConnectionButton: UIButton, Restylable { required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.setupView() + self.accessibilityIdentifier = AccessibilityId.Dashboard.connectionButton } deinit { @@ -77,13 +78,13 @@ class PIAConnectionButton: UIButton, Restylable { private func setupView() { - self.accessibilityLabel = L10n.Dashboard.Accessibility.Vpn.button + self.accessibilityLabel = L10n.Localizable.Dashboard.Accessibility.Vpn.button //Notification when the theme has changed NotificationCenter.default.addObserver(self, selector: #selector(viewShouldRestyle), name: .PIAThemeDidChange, object: nil) //Image - let vpnImage = Asset.Piax.Dashboard.vpnButton.image.withRenderingMode(.alwaysTemplate) + let vpnImage = Asset.Images.Piax.Dashboard.vpnButton.image.withRenderingMode(.alwaysTemplate) self.setImage(vpnImage, for: []) displayLink = CADisplayLink(target: self, selector: #selector(redrawUpdate)) diff --git a/PIA VPN/PIAHotspotHelper.swift b/PIA VPN/PIAHotspotHelper.swift index c9ee827b0..9d6eee4b5 100644 --- a/PIA VPN/PIAHotspotHelper.swift +++ b/PIA VPN/PIAHotspotHelper.swift @@ -24,6 +24,7 @@ import Foundation import NetworkExtension import PIALibrary import SwiftyBeaver +import UIKit private let log = SwiftyBeaver.self @@ -41,9 +42,11 @@ public protocol PIAHotspotHelperDelegate: class { class PIAHotspotHelper { private var delegate: PIAHotspotHelperDelegate? + private let networkMonitor: NetworkMonitor - init(withDelegate delegate: PIAHotspotHelperDelegate? = nil) { + init(withDelegate delegate: PIAHotspotHelperDelegate? = nil, networkMonitor: NetworkMonitor = WifiNetworkMonitor()) { self.delegate = delegate + self.networkMonitor = networkMonitor } /** @@ -92,6 +95,13 @@ class PIAHotspotHelper { } response.deliver() } else if cmd.commandType == .evaluate { + + if AppPreferences.shared.showLeakProtectionNotifications { + weakSelf.checkForRFC1918VulnerableWifi(cmd: cmd) + } else { + Client.preferences.currentRFC1918VulnerableWifi = nil + } + if let currentNetwork = cmd.network { if !currentNetwork.isSecure { // Open WiFi log.info("Evaluate") @@ -122,12 +132,24 @@ class PIAHotspotHelper { } } + private func checkForRFC1918VulnerableWifi(cmd: NEHotspotHelperCommand) { + if networkMonitor.checkForRFC1918Vulnerability() { + log.info("HotspotHelper: APIHotspotDidDetectRFC1918VulnerableWifi detected") + Client.preferences.currentRFC1918VulnerableWifi = cmd.network?.ssid.trimmingCharacters(in: CharacterSet.whitespaces) + NotificationCenter.default.post(name: .DeviceDidConnectToRFC1918VulnerableWifi, object: nil) + } else { + log.info("HotspotHelper: APIHotspotDidDetectRFC1918VulnerableWifi NOT detected") + Client.preferences.currentRFC1918VulnerableWifi = nil + NotificationCenter.default.post(name: .DeviceDidConnectToRFC1918CompliantWifi, object: nil) + } + } + private func hotspotHelperMessage() -> String { if Client.preferences.nmtRulesEnabled, Client.preferences.useWiFiProtection { - return L10n.Hotspothelper.Display.Protected.name + return L10n.Localizable.Hotspothelper.Display.Protected.name } else { - return L10n.Hotspothelper.Display.name + return L10n.Localizable.Hotspothelper.Display.name } } @@ -200,3 +222,12 @@ class PIAHotspotHelper { } } + +public extension Notification.Name { + + /// Posted when device detects RFC1918 vulnerable Wifi + static let DeviceDidConnectToRFC1918VulnerableWifi: Notification.Name = Notification.Name("DeviceDidConnectToRFC1918VulnerableWifi") + + /// Posted when device detects RFC1918 compliant Wifi + static let DeviceDidConnectToRFC1918CompliantWifi: Notification.Name = Notification.Name("DeviceDidConnectToRFC1918CompliantWifi") +} diff --git a/PIA VPN/PIAPageControl.swift b/PIA VPN/PIAPageControl.swift index de0b14a2d..77ef66359 100644 --- a/PIA VPN/PIAPageControl.swift +++ b/PIA VPN/PIAPageControl.swift @@ -20,7 +20,7 @@ // Internet Access iOS Client. If not, see . // -import FXPageControl +import __PIALibraryNative class PIAPageControl: FXPageControl { override func draw(_ rect: CGRect) { diff --git a/PIA VPN/PIATunnelProvider+UI.swift b/PIA VPN/PIATunnelProvider+UI.swift index b97d7c017..3d36081b5 100644 --- a/PIA VPN/PIATunnelProvider+UI.swift +++ b/PIA VPN/PIATunnelProvider+UI.swift @@ -21,7 +21,8 @@ // import Foundation -import TunnelKit +import TunnelKitCore +import TunnelKitOpenVPN extension SocketType: CustomStringConvertible { public var description: String { diff --git a/PIA VPN/PIAWelcomeViewController.swift b/PIA VPN/PIAWelcomeViewController.swift new file mode 100644 index 000000000..4d93cfbe5 --- /dev/null +++ b/PIA VPN/PIAWelcomeViewController.swift @@ -0,0 +1,280 @@ +// +// PIAWelcomeViewController.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/19/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import PIALibrary + +/** + The welcome view controller is a graphic gateway to the PIA services. + */ +public class PIAWelcomeViewController: AutolayoutViewController, WelcomeCompletionDelegate, ConfigurationAccess, InAppAccess, BrandableNavigationBar { + + @IBOutlet private weak var buttonCancel: UIButton! + @IBOutlet private weak var buttonEnvironment: UIButton! + + var preset = Preset() + + var selectedPlanIndex: Int? + + var allPlans: [PurchasePlan]? + + private var pendingSignupRequest: SignupRequest? + weak var delegate: PIAWelcomeViewControllerDelegate? + + /// It's `true` if the controller was created with `Preset.isEphemeral`. + /// + /// - Seealso: `Preset.isEphemeral` + public var isEphemeral: Bool { + return preset.isEphemeral + } + + /** + Creates a wrapped `PIAWelcomeViewController` ready for presentation. + + - Parameter preset: The optional `Preset` to configure this controller with + - Parameter delegate: The `PIAWelcomeViewControllerDelegate` to handle raised events + */ + public static func with(preset: Preset? = nil, delegate: PIAWelcomeViewControllerDelegate? = nil) -> UIViewController { + let nav = StoryboardScene.Welcome.initialScene.instantiate() + + let vc = nav.topViewController as! PIAWelcomeViewController + if let customPreset = preset { + vc.preset = customPreset + } + vc.delegate = delegate + return nav + } + + deinit { + NotificationCenter.default.removeObserver(self) + } + + /// :nodoc: + public override func viewDidLoad() { + super.viewDidLoad() + + guard !preset.accountProvider.isLoggedIn else { + fatalError("You are already logged in, you might want to Client.database.truncate() to start clean") + } + + buttonCancel.isHidden = true + buttonEnvironment.isHidden = !accessedConfiguration.isDevelopment + buttonEnvironment.accessibilityIdentifier = Accessibility.Id.Welcome.environment + + #if os(iOS) + let nc = NotificationCenter.default + nc.addObserver(self, selector: #selector(inAppDidAddUncredited(notification:)), name: .__InAppDidAddUncredited, object: nil) + #endif + + } + + /// :nodoc: + public override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + if !preset.openFromDashboard { + self.navigationController?.setNavigationBarHidden(false, animated: true) + self.navigationItem.leftBarButtonItem = UIBarButtonItem( + image: Theme.current.palette.navigationBarBackIcon?.withRenderingMode(.alwaysOriginal), + style: .plain, + target: self, + action: #selector(back(_:)) + ) + self.navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Welcome.Redeem.Accessibility.back + } else { + if preset.allowsCancel { + self.navigationItem.leftBarButtonItem = UIBarButtonItem( + image: Asset.Images.iconClose.image.withRenderingMode(.alwaysOriginal), + style: .plain, + target: self, + action: #selector(cancelClicked(_:)) + ) + self.navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Ui.Global.cancel + } + } + + refreshEnvironmentButton() + } + + /// :nodoc: + public override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + tryRecoverSignupProcess() + } + + // MARK: Actions + @objc private func cancelClicked(_ sender: Any?) { + delegate?.welcomeControllerDidCancel(self) + } + + @IBAction private func toggleEnvironment(_ sender: Any?) { + if (Client.environment == .production) { + Client.environment = .staging + } else { + Client.environment = .production + } + Client.resetWebServices() + Client.providers.serverProvider.download(nil) + refreshEnvironmentButton() + } + + private func refreshEnvironmentButton() { + if (Client.environment == .production) { + buttonEnvironment.setTitle("Production", for: .normal) + } else { + buttonEnvironment.setTitle("Staging", for: .normal) + } + } + + private func tryRecoverSignupProcess() { + guard preset.shouldRecoverPendingSignup else { + return + } + guard let request = preset.accountProvider.lastSignupRequest else { + return + } + guard (pendingSignupRequest == nil) else { + return + } + guard accessedStore.hasUncreditedTransactions else { + return + } + pendingSignupRequest = request + perform(segue: StoryboardSegue.Welcome.signupViaRecoverSegue) + } + + /// :nodoc: + public override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if let vc = segue.destination as? WelcomePageViewController { + vc.preset = preset + vc.completionDelegate = self + vc.allPlans = allPlans + vc.selectedPlanIndex = selectedPlanIndex + } + // recover pending signup + else if (segue.identifier == StoryboardSegue.Welcome.signupViaRecoverSegue.rawValue) { + let nav = segue.destination as! UINavigationController + let vc = nav.topViewController as! SignupInProgressViewController + + guard let request = pendingSignupRequest else { + fatalError("Recovering signup and pendingSignupRequest is not set") + } + var metadata = SignupMetadata(email: request.email) + metadata.title = L10n.Signup.InProgress.title + metadata.bodySubtitle = L10n.Signup.InProgress.message + vc.metadata = metadata + vc.signupRequest = request + } + } + + // MARK: WelcomeCompletionDelegate + + func welcomeDidLogin(withUser user: UserAccount, topViewController: UIViewController) { + delegate?.welcomeController(self, didLoginWith: user, topViewController: topViewController) + } + + func welcomeDidSignup(withUser user: UserAccount, topViewController: UIViewController) { + delegate?.welcomeController(self, didSignupWith: user, topViewController: topViewController) + } + + // MARK: Notifications + + #if os(iOS) + @objc private func inAppDidAddUncredited(notification: Notification) { + tryRecoverSignupProcess() + } + #endif + + // MARK: Size classes + + // consider compact height in landscape + /// :nodoc: + public override var traitCollection: UITraitCollection { + if isLandscape { + return UITraitCollection(verticalSizeClass: .compact) + } + return super.traitCollection + } + + // MARK: Restylable + + /// :nodoc: + public override func viewShouldRestyle() { + super.viewShouldRestyle() + if !preset.isExpired { + navigationItem.titleView = NavigationLogoView() + } + else { + navigationItem.title = L10n.Welcome.Upgrade.header + } + Theme.current.applyPrincipalBackground(view) + Theme.current.applyNavigationBarStyle(to: self) + Theme.current.applyCancelButton(buttonCancel, appearance: .dark) + buttonEnvironment.setTitleColor(buttonCancel.titleColor(for: .normal), for: .normal) + } +} + +/// Receives events from a `PIAWelcomeViewController`. +public protocol PIAWelcomeViewControllerDelegate: class { + + /** + Invoked after a successful login. + + - Parameter welcomeController: The delegating controller + - Parameter user: The logged in `UserAccount` + */ + func welcomeController(_ welcomeController: PIAWelcomeViewController, didLoginWith user: UserAccount, topViewController: UIViewController) + + /** + Invoked after a successful signup. + + - Parameter welcomeController: The delegating controller + - Parameter user: The signed up `UserAccount` + */ + func welcomeController(_ welcomeController: PIAWelcomeViewController, didSignupWith user: UserAccount, topViewController: UIViewController) + + /** + Invoked after a cancel. + + - Parameter welcomeController: The delegating controller + */ + func welcomeControllerDidCancel(_ welcomeController: PIAWelcomeViewController) +} + +public extension PIAWelcomeViewControllerDelegate { + func welcomeControllerDidCancel(_ welcomeController: PIAWelcomeViewController) { + } +} + +protocol WelcomeChild: class { + var preset: Preset? { get set } + + var omitsSiblingLink: Bool { get set } + + var completionDelegate: WelcomeCompletionDelegate? { get set } +} + +protocol WelcomeCompletionDelegate: class { + func welcomeDidLogin(withUser user: UserAccount, topViewController: UIViewController) + + func welcomeDidSignup(withUser user: UserAccount, topViewController: UIViewController) +} diff --git a/PIA VPN/PemUtil.swift b/PIA VPN/PemUtil.swift index 2220f398f..e952cb829 100644 --- a/PIA VPN/PemUtil.swift +++ b/PIA VPN/PemUtil.swift @@ -22,7 +22,8 @@ // import Foundation -import TunnelKit +import TunnelKitCore +import TunnelKitOpenVPN public extension OpenVPN.Configuration { diff --git a/PIA VPN/ProtocolSettingsViewController.swift b/PIA VPN/ProtocolSettingsViewController.swift index c6821e6dc..4be151bf0 100644 --- a/PIA VPN/ProtocolSettingsViewController.swift +++ b/PIA VPN/ProtocolSettingsViewController.swift @@ -23,7 +23,8 @@ import UIKit import Popover import SwiftyBeaver import PIALibrary -import TunnelKit +import TunnelKitCore +import TunnelKitOpenVPN class ProtocolSettingsViewController: PIABaseSettingsViewController { @@ -74,7 +75,7 @@ class ProtocolSettingsViewController: PIABaseSettingsViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - styleNavigationBarWithTitle(L10n.Settings.Section.protocols) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Section.protocols) } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { @@ -98,6 +99,7 @@ class ProtocolSettingsViewController: PIABaseSettingsViewController { let height = heightForOptions(options) //Default height * 3 for 3 protocols let optionsView = ProtocolPopoverSelectionView(frame: CGRect(x: 0, y: 0, width: Int(width), height: height)) optionsView.pendingPreferences = self.pendingPreferences + optionsView.settingsDelegate = self.settingsDelegate optionsView.currentPopover = protocolPopover optionsView.protocols = options protocolPopover.show(optionsView, fromView: sender) @@ -211,7 +213,7 @@ class ProtocolSettingsViewController: PIABaseSettingsViewController { override func viewShouldRestyle() { super.viewShouldRestyle() - styleNavigationBarWithTitle(L10n.Settings.Section.general) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Section.general) // XXX: for some reason, UITableView is not affected by appearance updates if let viewContainer = viewContainer { Theme.current.applyPrincipalBackground(view) @@ -246,7 +248,7 @@ extension ProtocolSettingsViewController: UITableViewDelegate, UITableViewDataSo cell.textLabel?.numberOfLines = 0 cell.textLabel?.style(style: TextStyle.textStyle21) cell.backgroundColor = .clear - cell.textLabel?.text = L10n.Settings.Small.Packets.description + cell.textLabel?.text = L10n.Localizable.Settings.Small.Packets.description return cell } return nil @@ -259,12 +261,12 @@ extension ProtocolSettingsViewController: UITableViewDelegate, UITableViewDataSo case .protocolSelection: cell.detailTextLabel?.text = pendingPreferences.vpnType.vpnProtocol case .transport: - cell.detailTextLabel?.text = settingsDelegate.pendingOpenVPNSocketType?.rawValue ?? L10n.Global.automatic + cell.detailTextLabel?.text = settingsDelegate.pendingOpenVPNSocketType?.rawValue ?? L10n.Localizable.Global.automatic case .remotePort: if let port = settingsDelegate.pendingOpenVPNConfiguration.currentPort, port != ProtocolSettingsViewController.AUTOMATIC_PORT { cell.detailTextLabel?.text = port.description } else { - cell.detailTextLabel?.text = L10n.Global.automatic + cell.detailTextLabel?.text = L10n.Localizable.Global.automatic } case .dataEncryption: @@ -297,7 +299,7 @@ extension ProtocolSettingsViewController: UITableViewDelegate, UITableViewDataSo cell.accessoryType = .none } case .useSmallPackets: - cell.textLabel?.text = L10n.Settings.Small.Packets.title + cell.textLabel?.text = L10n.Localizable.Settings.Small.Packets.title cell.detailTextLabel?.text = nil cell.accessoryView = switchSmallPackets cell.selectionStyle = .none diff --git a/PIA VPN/PurchasePlanCell.swift b/PIA VPN/PurchasePlanCell.swift new file mode 100644 index 000000000..05e14b0f8 --- /dev/null +++ b/PIA VPN/PurchasePlanCell.swift @@ -0,0 +1,133 @@ +// +// PurchasePlanCell.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/19/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import PIALibrary + +class PurchasePlanCell: UICollectionViewCell, Restylable { + + // XXX + private static let textPlaceholder = " " + private static let pricePlaceholder = " " + private static let bestValueContainerHeight: CGFloat = 20.0 + private static let priceBottomConstant: CGFloat = 26.0 + + @IBOutlet private weak var viewContainer: UIView! + @IBOutlet private weak var viewBestValue: UIView! + @IBOutlet private weak var labelBestValue: UILabel! + @IBOutlet private weak var labelPlan: UILabel! + @IBOutlet private weak var labelPrice: UILabel! + @IBOutlet private weak var labelDetail: UILabel! + + @IBOutlet private weak var unselectedPlanImageView: UIImageView! + @IBOutlet private weak var selectedPlanImageView: UIImageView! + + @IBOutlet private weak var bestValueHeightConstraint: NSLayoutConstraint! + @IBOutlet weak var priceBottomConstraint: NSLayoutConstraint! + + override func awakeFromNib() { + super.awakeFromNib() + isSelected = false + + labelBestValue.text = Client.configuration.eligibleForTrial ? + "\(L10n.Welcome.Plan.bestValue.uppercased()) - FREE TRIAL" : + L10n.Welcome.Plan.bestValue.uppercased() + + selectedPlanImageView.alpha = 0 + self.accessibilityTraits = UIAccessibilityTraits.button + self.isAccessibilityElement = true + } + + func fill(plan: PurchasePlan) { + viewShouldRestyle() + + if plan.isDummy { + let pendingBackgroundColor = UIColor(white: 0.95, alpha: 1.0) + labelPlan.backgroundColor = pendingBackgroundColor + labelDetail.backgroundColor = pendingBackgroundColor + labelPrice.backgroundColor = pendingBackgroundColor + + labelPlan.text = PurchasePlanCell.textPlaceholder + labelDetail.text = PurchasePlanCell.textPlaceholder + labelPrice.text = PurchasePlanCell.pricePlaceholder + viewBestValue.isHidden = true + } else { + labelPlan.backgroundColor = .clear + labelDetail.backgroundColor = .clear + labelPrice.backgroundColor = .clear + + labelPlan.text = plan.title + labelDetail.text = plan.detail + labelPrice.text = L10n.Welcome.Plan.priceFormat(plan.monthlyPriceString) + self.accessibilityLabel = "\(plan.title) \(plan.detail) \(labelPrice.text)" + viewBestValue.isHidden = !plan.bestValue + if viewBestValue.isHidden { + bestValueHeightConstraint.constant = 0 + priceBottomConstraint.constant = 0 + } else { + bestValueHeightConstraint.constant = PurchasePlanCell.bestValueContainerHeight + priceBottomConstraint.constant = PurchasePlanCell.priceBottomConstant + } + + if plan.plan == Plan.yearly { + Theme.current.applyTitle(labelDetail, appearance: .dark) + Theme.current.applySmallInfo(labelPrice, appearance: .dark) + } else { + Theme.current.applyTitle(labelPrice, appearance: .dark) + Theme.current.applySmallInfo(labelDetail, appearance: .dark) + } + + self.layoutSubviews() + + accessibilityLabel = "\(plan.title), \(plan.accessibleMonthlyPriceString) \(L10n.Welcome.Plan.Accessibility.perMonth)" + } + viewBestValue.isHidden = !plan.bestValue + } + + override var isSelected: Bool { + didSet { + Theme.current.applyBorder(viewContainer, selected: isSelected) +// Theme.current.applyTitle(labelPrice, appearance:(isSelected ? .emphasis : .dark)) + + if isSelected { + UIView.animate(withDuration: 0.2, animations: { + self.selectedPlanImageView.alpha = 1 + }) + } else { + UIView.animate(withDuration: 0.2, animations: { + self.selectedPlanImageView.alpha = 0 + }) + } + } + } + + // MARK: Restylable + + func viewShouldRestyle() { + Theme.current.applyCorner(viewBestValue, factor: 1.0) + Theme.current.applyWarningBackground(viewBestValue) + Theme.current.applyBlackLabelInBox(labelBestValue) + Theme.current.applySubtitle(labelPlan) + Theme.current.applyTitle(labelPrice, appearance: .dark) + Theme.current.applySubtitle(labelDetail) + } +} diff --git a/PIA VPN/PurchaseViewController.swift b/PIA VPN/PurchaseViewController.swift new file mode 100644 index 000000000..e6950d59a --- /dev/null +++ b/PIA VPN/PurchaseViewController.swift @@ -0,0 +1,355 @@ +// +// PurchaseViewController.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/19/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import SwiftyBeaver +import PIALibrary + +private let log = SwiftyBeaver.self + +class PurchaseViewController: AutolayoutViewController, BrandableNavigationBar, WelcomeChild { + + private struct Cells { + static let plan = "PlanCell" + } + + @IBOutlet private weak var scrollView: UIScrollView! + + @IBOutlet private weak var labelTitle: UILabel! + @IBOutlet private weak var labelSubtitle: UILabel! + + @IBOutlet private weak var collectionPlans: UICollectionView! + + @IBOutlet private weak var textAgreement: UITextView! + + @IBOutlet private weak var buttonPurchase: PIAButton! + + var preset: Preset? + weak var completionDelegate: WelcomeCompletionDelegate? + var omitsSiblingLink = false + + var allPlans: [PurchasePlan] = [.dummy, .dummy] + + var selectedPlanIndex: Int? + + private var isExpired = false + private var signupEmail: String? + private var signupTransaction: InAppTransaction? + private var isPurchasing = false + + deinit { + NotificationCenter.default.removeObserver(self) + } + + override func viewDidLoad() { + super.viewDidLoad() + + guard let preset = self.preset else { + fatalError("Preset not propagated") + } + + isExpired = preset.isExpired + + styleButtons() + + collectionPlans.isUserInteractionEnabled = false + + self.navigationItem.leftBarButtonItem = UIBarButtonItem( + image: Theme.current.palette.navigationBarBackIcon?.withRenderingMode(.alwaysOriginal), + style: .plain, + target: self, + action: #selector(back(_:)) + ) + self.navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Welcome.Redeem.Accessibility.back + + if isExpired { + labelTitle.text = L10n.Welcome.Upgrade.title + labelTitle.textAlignment = .center + labelSubtitle.text = "" + } + else { + labelTitle.text = L10n.Welcome.Purchase.title + labelSubtitle.text = L10n.Welcome.Purchase.subtitle + } + textAgreement.attributedText = Theme.current.agreementText( + withMessage: L10n.Welcome.Agreement.message(""), + tos: L10n.Welcome.Agreement.Message.tos, + tosUrl: Client.configuration.tosUrl, + privacy: L10n.Welcome.Agreement.Message.privacy, + privacyUrl: Client.configuration.privacyUrl + ) + + let nc = NotificationCenter.default + nc.addObserver(self, selector: #selector(productsDidFetch(notification:)), name: .__InAppDidFetchProducts, object: nil) + + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + if let products = preset?.accountProvider.planProducts { + refreshPlans(products) + } else { + disableInteractions(fully: false) + } + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + + NotificationCenter.default.removeObserver(self) + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if (segue.identifier == StoryboardSegue.Welcome.signupViaPurchaseSegue.rawValue) { + let nav = segue.destination as! UINavigationController + let vc = nav.topViewController as! SignupInProgressViewController + + guard let email = signupEmail else { + fatalError("Signing up and signupEmail is not set") + } + var metadata = SignupMetadata(email: email) + metadata.title = L10n.Signup.InProgress.title + metadata.bodySubtitle = L10n.Signup.InProgress.message + vc.metadata = metadata + vc.signupRequest = SignupRequest(email: email, transaction: signupTransaction) + vc.preset = preset + vc.completionDelegate = completionDelegate + } + } + + /// Populate the view with the values from GetStartedView + /// - Parameters: + /// - plans: The available plans. + /// - selectedIndex: The selected plan from the previous screen. + func populateViewWith(plans: [PurchasePlan], andSelectedPlanIndex selectedIndex: Int) { + self.allPlans = plans + self.selectedPlanIndex = selectedIndex + } + + // MARK: Actions + + @IBAction func confirmPlan() { + + /** + self.performSegue(withIdentifier: StoryboardSegue.Welcome.confirmPurchaseVPNPlanSegue.rawValue, + sender: nil) + **/ + + if let index = selectedPlanIndex { + let plan = allPlans[index] + self.startPurchaseProcessWithEmail("", andPlan: plan) + } + + + } + + private func startPurchaseProcessWithEmail(_ email: String, + andPlan plan: PurchasePlan) { + + guard !Client.store.hasUncreditedTransactions else { + let alert = Macros.alert( + nil, + L10n.Signup.Purchase.Uncredited.Alert.message + ) + alert.addCancelAction(L10n.Signup.Purchase.Uncredited.Alert.Button.cancel) + alert.addActionWithTitle(L10n.Signup.Purchase.Uncredited.Alert.Button.recover) { + self.navigationController?.popToRootViewController(animated: true) + Macros.postNotification(.PIARecoverAccount) + } + present(alert, animated: true, completion: nil) + return + + } + + //textEmail.text = email + log.debug("Will purchase plan: \(plan.product)") + + isPurchasing = true + disableInteractions(fully: true) + self.showLoadingAnimation() + + preset?.accountProvider.purchase(plan: plan.plan) { (transaction, error) in + self.isPurchasing = false + self.enableInteractions() + self.hideLoadingAnimation() + + guard let transaction = transaction else { + if let error = error { + let message = error.localizedDescription + log.error("Purchase failed (error: \(error))") + Macros.displayImageNote(withImage: Asset.Images.iconWarning.image, + message: message) + } else { + log.warning("Cancelled purchase") + } + return + } + + log.debug("Purchased with transaction: \(transaction)") + + self.signupEmail = email + self.signupTransaction = transaction + self.perform(segue: StoryboardSegue.Welcome.signupViaPurchaseSegue) + } + + } + + private func refreshPlans(_ plans: [Plan: InAppProduct]) { + if let yearly = plans[.yearly] { + let purchase = PurchasePlan( + plan: .yearly, + product: yearly, + monthlyFactor: 12.0 + ) + + purchase.title = L10n.Welcome.Plan.Yearly.title + let currencySymbol = purchase.product.priceLocale.currencySymbol ?? "" + purchase.detail = L10n.Welcome.Plan.Yearly.detailFormat(currencySymbol, purchase.product.price.description) + purchase.bestValue = true + + allPlans[0] = purchase + + textAgreement.attributedText = Theme.current.agreementText( + withMessage: L10n.Welcome.Agreement.message(purchase.detail), + tos: L10n.Welcome.Agreement.Message.tos, + tosUrl: Client.configuration.tosUrl, + privacy: L10n.Welcome.Agreement.Message.privacy, + privacyUrl: Client.configuration.privacyUrl + ) + + } + if let monthly = plans[.monthly] { + let purchase = PurchasePlan( + plan: .monthly, + product: monthly, + monthlyFactor: 1.0 + ) + purchase.title = L10n.Welcome.Plan.Monthly.title + purchase.bestValue = false + + allPlans[1] = purchase + } + + collectionPlans.isUserInteractionEnabled = true + collectionPlans.reloadData() + if (selectedPlanIndex == nil) { + selectedPlanIndex = 0 + } + collectionPlans.selectItem(at: IndexPath(row: selectedPlanIndex!, section: 0), animated: false, scrollPosition: []) + } + + private func disableInteractions(fully: Bool) { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + self.showLoadingAnimation() + } + collectionPlans.isUserInteractionEnabled = false + if fully { + parent?.view.isUserInteractionEnabled = false + } + } + + private func enableInteractions() { + if !isPurchasing { //dont reenable the screen if we are still purchasing + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + self.hideLoadingAnimation() + } + collectionPlans.isUserInteractionEnabled = true + parent?.view.isUserInteractionEnabled = true + } + } + + // MARK: Notifications + + @objc private func productsDidFetch(notification: Notification) { + let products: [Plan: InAppProduct] = notification.userInfo(for: .products) + refreshPlans(products) + enableInteractions() + } + + // MARK: Restylable + + override func viewShouldRestyle() { + super.viewShouldRestyle() + Theme.current.applyNavigationBarStyle(to: self) + Theme.current.applyPrincipalBackground(view) + Theme.current.applyPrincipalBackground(scrollView) + Theme.current.applyPrincipalBackground(collectionPlans) + Theme.current.applyTitle(labelTitle, appearance: .dark) + Theme.current.applySubtitle(labelSubtitle) + Theme.current.applyLinkAttributes(textAgreement) + } + + private func styleButtons() { + buttonPurchase.setRounded() + buttonPurchase.style(style: TextStyle.Buttons.piaGreenButton) + if !isExpired { + buttonPurchase.setTitle(L10n.Signup.Purchase.Subscribe.now.uppercased(), for: []) + } + else { + buttonPurchase.setTitle(L10n.Welcome.Upgrade.Renew.now.uppercased(), for: []) + } + } + +} + +extension PurchaseViewController: UICollectionViewDataSource, UICollectionViewDelegate { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return allPlans.count + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let plan = allPlans[indexPath.row] + let cell = collectionPlans.dequeueReusableCell(withReuseIdentifier: Cells.plan, for: indexPath) as! PurchasePlanCell + cell.fill(plan: plan) + cell.isSelected = (indexPath.row == selectedPlanIndex) + return cell + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + selectedPlanIndex = indexPath.row + } +} + +extension PurchaseViewController: UICollectionViewDelegateFlowLayout { + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + let itemWidth = collectionView.bounds.size.width + let itemHeight = (collectionView.bounds.size.height - 13) / 2.0 + return CGSize(width: itemWidth, + height: itemHeight) + } +} + +extension PurchaseViewController: UITextViewDelegate { + func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool { + return true + } +} + +extension PurchaseViewController: UITextFieldDelegate { + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + //if (textField == textEmail) { + // signUp(nil) + //} + return true + } +} diff --git a/PIA VPN/RatingManager.swift b/PIA VPN/RatingManager.swift index 5546985db..164218318 100644 --- a/PIA VPN/RatingManager.swift +++ b/PIA VPN/RatingManager.swift @@ -33,26 +33,53 @@ class RatingManager { static let shared = RatingManager() + private var successDisconnectionsUntilPrompt: Int private var successConnectionsUntilPrompt: Int private var successConnectionsUntilPromptAgain: Int private var timeIntervalUntilPromptAgain: Double private var errorInConnectionsUntilPrompt: Int - + + private var isRatingFlagAvailable: Bool { + return Client.configuration.featureFlags.contains(Client.FeatureFlags.disableSystemRatingDialog) + } + + private var targetDisconnectionsReachedForPrompt: Bool { + guard AppPreferences.shared.successConnections < self.successConnectionsUntilPrompt else { + return false // We do not check this because alert was already shown + } + return AppPreferences.shared.successDisconnections == self.successDisconnectionsUntilPrompt + } + + private var targetConnectionsReachedForPrompt: Bool { + return AppPreferences.shared.successConnections == self.successConnectionsUntilPrompt + } + init() { + self.successDisconnectionsUntilPrompt = AppConfiguration.Rating.successDisconnectionsUntilPrompt self.successConnectionsUntilPrompt = AppConfiguration.Rating.successConnectionsUntilPrompt self.successConnectionsUntilPromptAgain = AppConfiguration.Rating.successConnectionsUntilPromptAgain self.errorInConnectionsUntilPrompt = AppConfiguration.Rating.errorInConnectionsUntilPrompt self.timeIntervalUntilPromptAgain = AppConfiguration.Rating.timeIntervalUntilPromptAgain } - func logSuccessConnection() { - - AppPreferences.shared.successConnections += 1 - if AppPreferences.shared.successConnections == self.successConnectionsUntilPrompt { + func handleConnectionStatusChanged() { + // By default do not use custom alert + // and comparison should be: when vpn is disconnected + if Client.providers.vpnProvider.vpnStatus == (isRatingFlagAvailable ? .connected : .disconnected) { + showAppReviewWith(customPopup: isRatingFlagAvailable) + } + } + + private func showAppReviewWith(customPopup useCustomDialog: Bool) { + let shouldShowRatingAlert = useCustomDialog ? targetConnectionsReachedForPrompt : targetDisconnectionsReachedForPrompt + if shouldShowRatingAlert { log.debug("Show rating") - reviewApp() + if useCustomDialog { + showCustomAlertForReview() + } else { + showDefaultAlertForReview() + } } else if AppPreferences.shared.canAskAgainForReview { - let now = Date() if AppPreferences.shared.successConnections >= self.successConnectionsUntilPromptAgain, @@ -62,10 +89,9 @@ class RatingManager { reviewAppWithoutPrompt() } } - } - func logError() { + func handleConnectionError() { if Client.daemons.isNetworkReachable { if AppPreferences.shared.failureConnections == self.errorInConnectionsUntilPrompt { askForConnectionIssuesFeedback() @@ -74,7 +100,15 @@ class RatingManager { AppPreferences.shared.failureConnections += 1 } } - + + private func handleRatingAlertCancel() { + log.debug("No review but maybe we can try in the future") + AppPreferences.shared.canAskAgainForReview = true + if AppPreferences.shared.lastRatingRejection == nil { + AppPreferences.shared.lastRatingRejection = Date() + } + } + private func openRatingViewInAppstore() { let urlStr = AppConstants.Reviews.appReviewUrl @@ -94,24 +128,68 @@ class RatingManager { SKStoreReviewController.requestReview() } - private func reviewApp() { + // MARK: Default Alerts + + private func showDefaultAlertForReview() { + guard let rootView = AppDelegate.getRootViewController() else { + return + } + + let sheet = Macros.alertController(L10n.Localizable.Rating.Enjoy.question, nil) + sheet.addAction(UIAlertAction(title: L10n.Localizable.Rating.Alert.Button.notreally, style: .default, handler: { action in + // Ask for feedback + let alert = self.createDefaultFeedbackDialog() + rootView.present(alert, animated: true, completion: nil) + })) + sheet.addAction(UIAlertAction(title: L10n.Localizable.Global.yes, style: .default, handler: { action in + let alert = self.createDefaultReviewAlert() + rootView.present(alert, animated: true, completion: nil) + })) + rootView.present(sheet, animated: true, completion: nil) + } + + private func createDefaultFeedbackDialog() -> UIAlertController { + let sheet = Macros.alertController(L10n.Localizable.Rating.Problems.question, L10n.Localizable.Rating.Problems.subtitle) + sheet.addAction(UIAlertAction(title: L10n.Localizable.Global.no, style: .default, handler: { action in + log.debug("No feedback") + })) + sheet.addAction(UIAlertAction(title: L10n.Localizable.Global.yes, style: .default, handler: { action in + self.openFeedbackWebsite() + })) + return sheet + } + + private func createDefaultReviewAlert() -> UIAlertController { + let sheet = Macros.alertController(L10n.Localizable.Rating.Rate.question, nil) + sheet.addAction(UIAlertAction(title: L10n.Localizable.Rating.Alert.Button.nothanks, style: .default, handler: { action in + self.handleRatingAlertCancel() + })) + sheet.addAction(UIAlertAction(title: L10n.Localizable.Rating.Alert.Button.oksure, style: .default, handler: { action in + self.openRatingViewInAppstore() + })) + return sheet + } + + // MARK: Custom Alerts + + private func showCustomAlertForReview() { - guard let rootView = AppDelegate.delegate().topViewControllerWithRootViewController(rootViewController: UIApplication.shared.keyWindow?.rootViewController) else { + guard let rootView = AppDelegate.getRootViewController() else { return } let sheet = Macros.alert( - L10n.Rating.Enjoy.question, - L10n.Rating.Enjoy.subtitle + L10n.Localizable.Rating.Enjoy.question, + L10n.Localizable.Rating.Enjoy.subtitle ) - sheet.addCancelActionWithTitle(L10n.Global.no, handler: { + sheet.addCancelActionWithTitle(L10n.Localizable.Global.no, handler: { // Ask for feedback - let alert = self.feedback() + let alert = self.createCustomFeedbackDialog() rootView.present(alert, animated: true, completion: nil) }) - sheet.addActionWithTitle(L10n.Global.yes) { - let alert = self.askForReview() + sheet.addActionWithTitle(L10n.Localizable.Global.yes) { + let alert = self.createCustomReviewDialog() rootView.present(alert, animated: true, completion: nil) } @@ -119,17 +197,17 @@ class RatingManager { } - private func feedback() -> PopupDialog { + private func createCustomFeedbackDialog() -> PopupDialog { let sheet = Macros.alert( - L10n.Rating.Problems.question, - L10n.Rating.Problems.subtitle + L10n.Localizable.Rating.Problems.question, + L10n.Localizable.Rating.Problems.subtitle ) - sheet.addCancelActionWithTitle(L10n.Global.no, handler: { + sheet.addCancelActionWithTitle(L10n.Localizable.Global.no, handler: { log.debug("No feedback") }) - sheet.addActionWithTitle(L10n.Global.yes) { + sheet.addActionWithTitle(L10n.Localizable.Global.yes) { self.openFeedbackWebsite() } @@ -137,21 +215,17 @@ class RatingManager { } - private func askForReview() -> PopupDialog { + private func createCustomReviewDialog() -> PopupDialog { let sheet = Macros.alert( - L10n.Rating.Rate.question, - L10n.Rating.Rate.subtitle + L10n.Localizable.Rating.Review.question, + L10n.Localizable.Rating.Rate.subtitle ) - sheet.addCancelActionWithTitle(L10n.Global.no, handler: { - log.debug("No review but maybe we can try in the future") - AppPreferences.shared.canAskAgainForReview = true - if AppPreferences.shared.lastRatingRejection == nil { - AppPreferences.shared.lastRatingRejection = Date() - } + sheet.addCancelActionWithTitle(L10n.Localizable.Global.no, handler: { + self.handleRatingAlertCancel() }) - sheet.addActionWithTitle(L10n.Global.yes) { + sheet.addActionWithTitle(L10n.Localizable.Global.yes) { self.openRatingViewInAppstore() } @@ -161,17 +235,17 @@ class RatingManager { private func askForConnectionIssuesFeedback() { - guard let rootView = AppDelegate.delegate().topViewControllerWithRootViewController(rootViewController: UIApplication.shared.keyWindow?.rootViewController) else { + guard let rootView = AppDelegate.getRootViewController() else { return } let sheet = Macros.alert( - L10n.Rating.Error.question, - L10n.Rating.Error.subtitle + L10n.Localizable.Rating.Error.question, + L10n.Localizable.Rating.Error.subtitle ) - sheet.addCancelAction(L10n.Global.close) + sheet.addCancelAction(L10n.Localizable.Global.close) - sheet.addActionWithTitle(L10n.Rating.Error.Button.send) { + sheet.addActionWithTitle(L10n.Localizable.Rating.Error.Button.send) { self.openFeedbackWebsite() } diff --git a/PIA VPN/RegionCell.swift b/PIA VPN/RegionCell.swift index e3d4a2d54..bff2eb1d8 100644 --- a/PIA VPN/RegionCell.swift +++ b/PIA VPN/RegionCell.swift @@ -174,16 +174,16 @@ class RegionCell: UITableViewCell, Restylable { private func updateFavoriteImage() { self.isFavorite ? - self.favoriteImageView.image = Asset.Piax.Global.favoriteSelected.image : + self.favoriteImageView.image = Asset.Images.Piax.Global.favoriteSelected.image : Theme.current.applyFavoriteUnselectedImage(self.favoriteImageView) favoriteButton.accessibilityLabel = self.isFavorite ? - L10n.Region.Accessibility.favorite : - L10n.Region.Accessibility.unfavorite + L10n.Localizable.Region.Accessibility.favorite : + L10n.Localizable.Region.Accessibility.unfavorite } private func updateOfflineImage() { - self.favoriteImageView.image = Asset.offlineServerIcon.image - self.favoriteButton.accessibilityLabel = L10n.Global.disabled + self.favoriteImageView.image = Asset.Images.offlineServerIcon.image + self.favoriteButton.accessibilityLabel = L10n.Localizable.Global.disabled } } diff --git a/PIA VPN/RegionsViewController.swift b/PIA VPN/RegionsViewController.swift index 6fee90758..cce7a9a74 100644 --- a/PIA VPN/RegionsViewController.swift +++ b/PIA VPN/RegionsViewController.swift @@ -67,7 +67,7 @@ class RegionsViewController: AutolayoutViewController { override func viewDidLoad() { super.viewDidLoad() - title = L10n.Menu.Item.region + title = L10n.Localizable.Menu.Item.region var servers = Client.providers.serverProvider.currentServers if Client.configuration.isDevelopment, let customServers = AppConstants.Servers.customServers { @@ -128,12 +128,12 @@ class RegionsViewController: AutolayoutViewController { private func setupRightBarButton() { navigationItem.rightBarButtonItem = UIBarButtonItem( - image: Asset.Piax.Global.iconFilter.image, + image: Asset.Images.Piax.Global.iconFilter.image, style: .plain, target: self, action: #selector(showFilter(_:)) ) - navigationItem.rightBarButtonItem?.accessibilityLabel = L10n.Region.Accessibility.filter + navigationItem.rightBarButtonItem?.accessibilityLabel = L10n.Localizable.Region.Accessibility.filter } override func dismissModal() { @@ -149,7 +149,7 @@ class RegionsViewController: AutolayoutViewController { private func setupSearchBarController() { searchController.searchResultsUpdater = self searchController.obscuresBackgroundDuringPresentation = false - searchController.searchBar.placeholder = L10n.Region.Search.placeholder + searchController.searchBar.placeholder = L10n.Localizable.Region.Search.placeholder self.tableView.tableHeaderView = self.searchController.searchBar searchController.hidesNavigationBarDuringPresentation = false @@ -158,7 +158,7 @@ class RegionsViewController: AutolayoutViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - styleNavigationBarWithTitle(L10n.Menu.Item.region) + styleNavigationBarWithTitle(L10n.Localizable.Menu.Item.region) setupRightBarButton() tableView.reloadData() @@ -194,17 +194,17 @@ class RegionsViewController: AutolayoutViewController { } let popup = PopupDialog(title: nil, - message: L10n.Region.Filter.sortby.uppercased()) + message: L10n.Localizable.Region.Filter.sortby.uppercased()) - let buttonName = DefaultButton(title: L10n.Region.Filter.name.uppercased(), dismissOnTap: true) { + let buttonName = DefaultButton(title: L10n.Localizable.Region.Filter.name.uppercased(), dismissOnTap: true) { AppPreferences.shared.regionFilter = .name self.filterServers() } - let buttonLatency = DefaultButton(title: L10n.Region.Filter.latency.uppercased(), dismissOnTap: true) { + let buttonLatency = DefaultButton(title: L10n.Localizable.Region.Filter.latency.uppercased(), dismissOnTap: true) { AppPreferences.shared.regionFilter = .latency self.filterServers() } - let buttonFavorites = DefaultButton(title: L10n.Region.Filter.favorites.uppercased(), dismissOnTap: true) { + let buttonFavorites = DefaultButton(title: L10n.Localizable.Region.Filter.favorites.uppercased(), dismissOnTap: true) { AppPreferences.shared.regionFilter = .favorite self.filterServers() } @@ -246,7 +246,7 @@ class RegionsViewController: AutolayoutViewController { } @objc private func viewHasRotated() { - styleNavigationBarWithTitle(L10n.Menu.Item.region) + styleNavigationBarWithTitle(L10n.Localizable.Menu.Item.region) } // MARK: Notifications @@ -267,7 +267,7 @@ class RegionsViewController: AutolayoutViewController { override func viewShouldRestyle() { super.viewShouldRestyle() - styleNavigationBarWithTitle(L10n.Menu.Item.region) + styleNavigationBarWithTitle(L10n.Localizable.Menu.Item.region) if let viewContainer = viewContainer { Theme.current.applyRegionSolidLightBackground(view) diff --git a/PIA VPN/RestoreSignupViewController.swift b/PIA VPN/RestoreSignupViewController.swift new file mode 100644 index 000000000..661a5385f --- /dev/null +++ b/PIA VPN/RestoreSignupViewController.swift @@ -0,0 +1,202 @@ +// +// RestoreSignupViewController.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/21/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import SwiftyBeaver +import PIALibrary + +private let log = SwiftyBeaver.self + +public class RestoreSignupViewController: AutolayoutViewController, BrandableNavigationBar, WelcomeChild { + + var omitsSiblingLink = false + + var completionDelegate: WelcomeCompletionDelegate? + + @IBOutlet private weak var scrollView: UIScrollView! + + @IBOutlet private weak var viewModal: UIView! + + @IBOutlet private weak var labelTitle: UILabel! + + @IBOutlet private weak var labelDescription: UILabel! + + @IBOutlet private weak var textEmail: BorderedTextField! + + @IBOutlet private weak var buttonRestorePurchase: PIAButton! + + var preset: Preset? + + private var signupEmail: String? + private var isRunningActivity = false + + deinit { + NotificationCenter.default.removeObserver(self) + } + + override public func viewDidLoad() { + super.viewDidLoad() + + self.navigationController?.setNavigationBarHidden(false, animated: true) + self.navigationItem.leftBarButtonItem = UIBarButtonItem( + image: Theme.current.palette.navigationBarBackIcon?.withRenderingMode(.alwaysOriginal), + style: .plain, + target: self, + action: #selector(back(_:)) + ) + self.navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Welcome.Redeem.Accessibility.back + + labelTitle.text = L10n.Welcome.Restore.title + labelDescription.text = L10n.Welcome.Restore.subtitle + textEmail.placeholder = L10n.Welcome.Restore.Email.placeholder + + textEmail.text = preset?.purchaseEmail + + // XXX: signup scrolling hack, disable on iPad and iPhone Plus + if Macros.isDeviceBig { + scrollView.isScrollEnabled = false + } + + styleRestoreButton() + } + + override public func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + enableInteractions(true) + } + + override public func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // signup after receipt restore + if (segue.identifier == StoryboardSegue.Welcome.signupViaRestoreSegue.rawValue) { + let nav = segue.destination as! UINavigationController + let vc = nav.topViewController as! SignupInProgressViewController + + guard let email = signupEmail else { + fatalError("Signing up and signupEmail is not set") + } + var metadata = SignupMetadata(email: email) + metadata.title = L10n.Signup.InProgress.title + metadata.bodySubtitle = L10n.Signup.InProgress.message + vc.metadata = metadata + vc.preset = preset + vc.signupRequest = SignupRequest(email: email) + vc.completionDelegate = completionDelegate + } + } + + // MARK: Actions + + @IBAction private func restorePurchase(_ sender: Any?) { + guard !isRunningActivity else { + return + } + + guard let email = textEmail.text, Validator.validate(email: email.trimmed()) else { + signupEmail = nil + textEmail.becomeFirstResponder() + Macros.displayImageNote(withImage: Asset.Images.iconWarning.image, + message: L10n.Welcome.Purchase.Error.validation) + self.status = .error(element: textEmail) + return + } + + self.status = .restore(element: textEmail) + signupEmail = email.trimmed() + + enableInteractions(false) + isRunningActivity = true + self.showLoadingAnimation() + preset?.accountProvider.restorePurchases { (error) in + self.hideLoadingAnimation() + self.isRunningActivity = false + if let _ = error { + self.reportRestoreFailure(error) + self.enableInteractions(true) + return + } + self.reportRestoreSuccess() + } + } + + private func reportRestoreSuccess() { + log.debug("Restored payment receipt, redeeming..."); + + guard let email = signupEmail else { + fatalError("Restore receipt and signupEmail is not set") + } + self.restoreController(self, + didRefreshReceiptWith: email) + } + + private func reportRestoreFailure(_ optionalError: Error?) { + var message = optionalError?.localizedDescription ?? L10n.Welcome.Iap.Error.title + if let error = optionalError { + log.error("Failed to restore payment receipt (error: \(error))") + } else { + log.error("Failed to restore payment receipt") + } + Macros.displayImageNote(withImage: Asset.Images.iconWarning.image, + message: message) + + } + + private func enableInteractions(_ enable: Bool) { + textEmail.isEnabled = enable + } + + // MARK: Restylable + + override public func viewShouldRestyle() { + super.viewShouldRestyle() + navigationItem.titleView = NavigationLogoView() + Theme.current.applyNavigationBarStyle(to: self) + Theme.current.applyPrincipalBackground(view) + Theme.current.applyPrincipalBackground(viewModal) + Theme.current.applyTitle(labelTitle, appearance: .dark) + Theme.current.applySubtitle(labelDescription) + Theme.current.applyInput(textEmail) + } + + private func styleRestoreButton() { + buttonRestorePurchase.setRounded() + buttonRestorePurchase.style(style: TextStyle.Buttons.piaGreenButton) + buttonRestorePurchase.setTitle(L10n.Welcome.Restore.submit.uppercased(), + for: []) + } + + private func restoreController(_ restoreController: RestoreSignupViewController, didRefreshReceiptWith email: String) { + self.signupEmail = email + self.perform(segue: StoryboardSegue.Welcome.signupViaRestoreSegue) + } + +} + +extension RestoreSignupViewController: UITextFieldDelegate { + public func textFieldShouldReturn(_ textField: UITextField) -> Bool { + if (textField == textEmail) { + restorePurchase(nil) + } + return true + } +} + diff --git a/PIA VPN/Server+Automatic.swift b/PIA VPN/Server+Automatic.swift index e33a961af..7b3180990 100644 --- a/PIA VPN/Server+Automatic.swift +++ b/PIA VPN/Server+Automatic.swift @@ -26,7 +26,7 @@ import PIALibrary extension Server { static let automatic = Server( serial: "", - name: L10n.Global.automatic, + name: L10n.Localizable.Global.automatic, country: "universal", hostname: "auto.bogus.domain", pingAddress: nil, diff --git a/PIA VPN/Server+UI.swift b/PIA VPN/Server+UI.swift index 7d2cbf519..970d37b76 100644 --- a/PIA VPN/Server+UI.swift +++ b/PIA VPN/Server+UI.swift @@ -22,7 +22,8 @@ import Foundation import PIALibrary -import AlamofireImage +import Alamofire +import UIKit extension Server: CustomStringConvertible { func name(forStatus status: VPNStatus) -> String { @@ -40,9 +41,9 @@ extension Server: CustomStringConvertible { return localizedName case .connecting: - return L10n.Dashboard.Vpn.connecting + return L10n.Localizable.Dashboard.Vpn.connecting case .disconnecting: - return L10n.Dashboard.Vpn.disconnecting + return L10n.Localizable.Dashboard.Vpn.disconnecting case .disconnected, .unknown: return localizedName } diff --git a/PIA VPN/ServerProvider+UI.swift b/PIA VPN/ServerProvider+UI.swift index 77b6ca710..228b24891 100644 --- a/PIA VPN/ServerProvider+UI.swift +++ b/PIA VPN/ServerProvider+UI.swift @@ -31,6 +31,10 @@ extension Client.Preferences { return preferredServer ?? .automatic } set { + guard newValue != displayedServer else { + connectToSelectedServerIfNeeded() + return + } let ed = editable() if newValue.isAutomatic { ed.preferredServer = nil @@ -41,13 +45,21 @@ extension Client.Preferences { let action = ed.requiredVPNAction() ed.commit() - action?.execute { (error) in - let vpn = Client.providers.vpnProvider - if (vpn.vpnStatus != .disconnected) { - vpn.reconnect(after: nil, forceDisconnect: true, nil) - } else { - vpn.connect(nil) - } + action?.execute { [weak self] (error) in + self?.connectToSelectedServerIfNeeded(shouldReconnect: true) + } + } + } + + private func connectToSelectedServerIfNeeded(shouldReconnect: Bool = false) { + let vpn = Client.providers.vpnProvider + + switch vpn.vpnStatus { + case .disconnected: + vpn.connect(nil) + default: + if shouldReconnect { + vpn.reconnect(after: nil, forceDisconnect: true, nil) } } } diff --git a/PIA VPN/SettingOptions.swift b/PIA VPN/SettingOptions.swift index cbb745cee..667fcfcea 100644 --- a/PIA VPN/SettingOptions.swift +++ b/PIA VPN/SettingOptions.swift @@ -35,12 +35,12 @@ public enum SettingOptions: Int, EnumsBuilder { public func localizedTitleMessage() -> String { switch self { - case .general: return L10n.Settings.Section.general - case .protocols: return L10n.Settings.Section.protocols - case .network: return L10n.Settings.Section.network - case .privacyFeatures: return L10n.Settings.Section.privacyFeatures - case .automation: return L10n.Settings.Section.automation - case .help: return L10n.Settings.Section.help + case .general: return L10n.Localizable.Settings.Section.general + case .protocols: return L10n.Localizable.Settings.Section.protocols + case .network: return L10n.Localizable.Settings.Section.network + case .privacyFeatures: return L10n.Localizable.Settings.Section.privacyFeatures + case .automation: return L10n.Localizable.Settings.Section.automation + case .help: return L10n.Localizable.Settings.Section.help case .development: return "Development" } } @@ -59,13 +59,13 @@ public enum SettingOptions: Int, EnumsBuilder { public func imageForSection() -> UIImage { switch self { - case .general: return Asset.Piax.Settings.iconGeneral.image - case .protocols: return Asset.Piax.Settings.iconProtocols.image - case .network: return Asset.Piax.Settings.iconNetwork.image - case .privacyFeatures: return Asset.Piax.Settings.iconPrivacy.image - case .automation: return Asset.Piax.Settings.iconAutomation.image - case .help: return Asset.Piax.Settings.iconAbout.image - case .development: return Asset.Piax.Settings.iconGeneral.image + case .general: return Asset.Images.Piax.Settings.iconGeneral.image + case .protocols: return Asset.Images.Piax.Settings.iconProtocols.image + case .network: return Asset.Images.Piax.Settings.iconNetwork.image + case .privacyFeatures: return Asset.Images.Piax.Settings.iconPrivacy.image + case .automation: return Asset.Images.Piax.Settings.iconAutomation.image + case .help: return Asset.Images.Piax.Settings.iconAbout.image + case .development: return Asset.Images.Piax.Settings.iconGeneral.image } } @@ -104,11 +104,11 @@ public enum GeneralSections: Int, SettingSection, EnumsBuilder { public func localizedTitleMessage() -> String { switch self { - case .connectSiri: return L10n.Siri.Shortcuts.Connect.Row.title - case .disconnectSiri: return L10n.Siri.Shortcuts.Disconnect.Row.title - case .showGeoRegions: return L10n.Settings.Geo.Servers.description - case .showServiceCommunicationMessages: return L10n.Inapp.Messages.Toggle.title - case .resetSettings: return L10n.Settings.Reset.Defaults.title + case .connectSiri: return L10n.Localizable.Siri.Shortcuts.Connect.Row.title + case .disconnectSiri: return L10n.Localizable.Siri.Shortcuts.Disconnect.Row.title + case .showGeoRegions: return L10n.Localizable.Settings.Geo.Servers.description + case .showServiceCommunicationMessages: return L10n.Localizable.Inapp.Messages.Toggle.title + case .resetSettings: return L10n.Localizable.Settings.Reset.Defaults.title } } @@ -139,12 +139,12 @@ public enum ProtocolsSections: Int, SettingSection, EnumsBuilder { public func localizedTitleMessage() -> String { switch self { - case .protocolSelection: return L10n.Settings.Connection.VpnProtocol.title - case .transport: return L10n.Settings.Connection.Transport.title - case .remotePort: return L10n.Settings.Connection.RemotePort.title - case .dataEncryption: return L10n.Settings.Encryption.Cipher.title - case .handshake: return L10n.Settings.Encryption.Handshake.title - case .useSmallPackets: return L10n.Settings.Small.Packets.title + case .protocolSelection: return L10n.Localizable.Settings.Connection.VpnProtocol.title + case .transport: return L10n.Localizable.Settings.Connection.Transport.title + case .remotePort: return L10n.Localizable.Settings.Connection.RemotePort.title + case .dataEncryption: return L10n.Localizable.Settings.Encryption.Cipher.title + case .handshake: return L10n.Localizable.Settings.Encryption.Handshake.title + case .useSmallPackets: return L10n.Localizable.Settings.Small.Packets.title } } @@ -190,27 +190,33 @@ public enum NetworkSections: Int, SettingSection, EnumsBuilder { public enum PrivacyFeaturesSections: Int, SettingSection, EnumsBuilder { case killswitch = 0 + case leakProtection + case allowAccessOnLocalNetwork case safariContentBlocker case refresh public func localizedTitleMessage() -> String { switch self { - case .killswitch: return L10n.Settings.ApplicationSettings.KillSwitch.title - case .safariContentBlocker: return L10n.Settings.ContentBlocker.title - case .refresh: return L10n.Settings.ContentBlocker.Refresh.title + case .killswitch: return L10n.Localizable.Settings.ApplicationSettings.KillSwitch.title + case .leakProtection: return L10n.Localizable.Settings.ApplicationSettings.LeakProtection.title + case .allowAccessOnLocalNetwork: return L10n.Localizable.Settings.ApplicationSettings.AllowLocalNetwork.title + case .safariContentBlocker: return L10n.Localizable.Settings.ContentBlocker.title + case .refresh: return L10n.Localizable.Settings.ContentBlocker.Refresh.title } } public func localizedSubtitleMessage() -> String { switch self { case .killswitch: return "" + case .leakProtection: return "" + case .allowAccessOnLocalNetwork: return "" case .safariContentBlocker: return "" case .refresh: return "" } } public static func all() -> [Self] { - return [.killswitch, .safariContentBlocker, .refresh] + return [.killswitch, .leakProtection, .allowAccessOnLocalNetwork, .safariContentBlocker, .refresh] } } @@ -222,8 +228,8 @@ public enum AutomationSections: Int, SettingSection, EnumsBuilder { public func localizedTitleMessage() -> String { switch self { - case .automation: return L10n.Network.Management.Tool.Enable.automation - case .manageAutomation: return L10n.Network.Management.Tool.title + case .automation: return L10n.Localizable.Network.Management.Tool.Enable.automation + case .manageAutomation: return L10n.Localizable.Network.Management.Tool.title } } @@ -250,11 +256,11 @@ public enum HelpSections: Int, SettingSection, EnumsBuilder { public func localizedTitleMessage() -> String { switch self { - case .sendDebugLogs: return L10n.Settings.ApplicationInformation.Debug.title - case .kpiShareStatistics: return L10n.Settings.Service.Quality.Share.title - case .kpiViewEvents: return L10n.Settings.Service.Quality.Show.title - case .latestNews: return L10n.Settings.Cards.History.title - case .version: return L10n.Global.version + case .sendDebugLogs: return L10n.Localizable.Settings.ApplicationInformation.Debug.title + case .kpiShareStatistics: return L10n.Localizable.Settings.Service.Quality.Share.title + case .kpiViewEvents: return L10n.Localizable.Settings.Service.Quality.Show.title + case .latestNews: return L10n.Localizable.Settings.Cards.History.title + case .version: return L10n.Localizable.Global.version } } @@ -289,6 +295,9 @@ public enum DevelopmentSections: Int, SettingSection, EnumsBuilder { case resolveGoogleAdsDomain case deleteKeychain case crash + case leakProtectionFlag + case leakProtectionNotificationsFlag + case dynamicIslandLiveActivityFlag public func localizedTitleMessage() -> String { switch self { @@ -301,6 +310,9 @@ public enum DevelopmentSections: Int, SettingSection, EnumsBuilder { case .resolveGoogleAdsDomain: return "Resolve Google Ads Domain" case .deleteKeychain: return "Delete the Keychain" case .crash: return "Crash the app" + case .leakProtectionFlag: return "FF - Leak Protection" + case .leakProtectionNotificationsFlag: return "FF - Leak Protection Notifications" + case .dynamicIslandLiveActivityFlag: return "FF - Dynamic Island Live Activity" } } @@ -315,11 +327,14 @@ public enum DevelopmentSections: Int, SettingSection, EnumsBuilder { case .resolveGoogleAdsDomain: return "" case .deleteKeychain: return "" case .crash: return "" + case .leakProtectionFlag: return "" + case .leakProtectionNotificationsFlag: return "" + case .dynamicIslandLiveActivityFlag: return "" } } public static func all() -> [Self] { - return [.stagingVersion, .customServers, .publicUsername, .username, .password, .environment, .resolveGoogleAdsDomain, .deleteKeychain, .crash] + return [.stagingVersion, .customServers, .publicUsername, .username, .password, .environment, .resolveGoogleAdsDomain, .deleteKeychain, .crash, .leakProtectionFlag, .leakProtectionNotificationsFlag, .dynamicIslandLiveActivityFlag] } } diff --git a/PIA VPN/Settings/AutomationSettingsViewController.swift b/PIA VPN/Settings/AutomationSettingsViewController.swift index ffdc29185..93ebf643a 100644 --- a/PIA VPN/Settings/AutomationSettingsViewController.swift +++ b/PIA VPN/Settings/AutomationSettingsViewController.swift @@ -47,7 +47,7 @@ class AutomationSettingsViewController: PIABaseSettingsViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - styleNavigationBarWithTitle(L10n.Settings.Section.automation) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Section.automation) } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { @@ -88,7 +88,7 @@ class AutomationSettingsViewController: PIABaseSettingsViewController { override func viewShouldRestyle() { super.viewShouldRestyle() - styleNavigationBarWithTitle(L10n.Settings.Section.automation) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Section.automation) // XXX: for some reason, UITableView is not affected by appearance updates if let viewContainer = viewContainer { Theme.current.applyPrincipalBackground(view) @@ -113,7 +113,7 @@ extension AutomationSettingsViewController: UITableViewDelegate, UITableViewData cell.textLabel?.numberOfLines = 0 cell.textLabel?.style(style: TextStyle.textStyle21) cell.backgroundColor = .clear - cell.textLabel?.text = L10n.Settings.Hotspothelper.description + cell.textLabel?.text = L10n.Localizable.Settings.Hotspothelper.description return cell } return nil @@ -161,7 +161,7 @@ extension AutomationSettingsViewController: UITableViewDelegate, UITableViewData cell.selectionStyle = .none switchEnableNMT.isOn = Client.preferences.nmtRulesEnabled case .manageAutomation: - cell.textLabel?.text = L10n.Network.Management.Tool.title + cell.textLabel?.text = L10n.Localizable.Network.Management.Tool.title } Theme.current.applySecondaryBackground(cell) diff --git a/PIA VPN/Settings/DevelopmentSettingsViewController.swift b/PIA VPN/Settings/DevelopmentSettingsViewController.swift index 0199d0e93..44faf6635 100644 --- a/PIA VPN/Settings/DevelopmentSettingsViewController.swift +++ b/PIA VPN/Settings/DevelopmentSettingsViewController.swift @@ -32,6 +32,9 @@ class DevelopmentSettingsViewController: PIABaseSettingsViewController { @IBOutlet weak var tableView: UITableView! private lazy var switchEnvironment = UISwitch() + private lazy var switchLeakProtectionFlag = UISwitch() + private lazy var switchLeakProtectionNotificationsFlag = UISwitch() + private lazy var switchDynamicIslandLiveActivityFlag = UISwitch() private var controller: OptionsViewController? override func viewDidLoad() { @@ -44,6 +47,8 @@ class DevelopmentSettingsViewController: PIABaseSettingsViewController { tableView.delegate = self tableView.dataSource = self switchEnvironment.addTarget(self, action: #selector(toggleEnv(_:)), for: .valueChanged) + + addFeatureFlagsTogglesActions() NotificationCenter.default.addObserver(self, selector: #selector(reloadSettings), name: .PIASettingsHaveChanged, object: nil) } @@ -145,7 +150,27 @@ extension DevelopmentSettingsViewController: UITableViewDelegate, UITableViewDat case .crash: cell.textLabel?.text = "Crash" cell.detailTextLabel?.text = nil + case .leakProtectionFlag: + cell.textLabel?.text = "FF - Leak Protection" + cell.detailTextLabel?.text = nil + cell.accessoryView = switchLeakProtectionFlag + cell.selectionStyle = .none + switchLeakProtectionFlag.isOn = AppPreferences.shared.showLeakProtection + case .leakProtectionNotificationsFlag: + cell.textLabel?.text = "FF - Leak Protection Notifications" + cell.detailTextLabel?.text = nil + cell.accessoryView = switchLeakProtectionNotificationsFlag + cell.selectionStyle = .none + switchLeakProtectionNotificationsFlag.isOn = AppPreferences.shared.showLeakProtectionNotifications + case .dynamicIslandLiveActivityFlag: + cell.textLabel?.text = "FF - Dynamic Island Live Activity" + cell.detailTextLabel?.text = nil + cell.accessoryView = switchDynamicIslandLiveActivityFlag + cell.selectionStyle = .none + switchDynamicIslandLiveActivityFlag.isOn = AppPreferences.shared.showDynamicIslandLiveActivity + } + } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { @@ -231,7 +256,7 @@ extension DevelopmentSettingsViewController: UITableViewDelegate, UITableViewDat } case .crash: - fatalError("Crashing staging app") + crashStagingApp() case .deleteKeychain: deleteKeychain() default: break @@ -240,6 +265,10 @@ extension DevelopmentSettingsViewController: UITableViewDelegate, UITableViewDat tableView.deselectRow(at: indexPath, animated: true) } + private func crashStagingApp() { + NSException(name: NSExceptionName(rawValue: "App Crash"), reason: "Crashing the staging app manually").raise() + } + private func deleteKeychain() { let secItemClasses = [kSecClassGenericPassword, kSecClassInternetPassword, kSecClassCertificate, kSecClassKey, kSecClassIdentity] for itemClass in secItemClasses { @@ -259,7 +288,7 @@ extension DevelopmentSettingsViewController: UITableViewDelegate, UITableViewDat } let alert = Macros.alert(nil, addresses.joined(separator: ",")) - alert.addDefaultAction(L10n.Global.close) + alert.addDefaultAction(L10n.Localizable.Global.close) self.present(alert, animated: true, completion: nil) } } @@ -342,3 +371,28 @@ extension DevelopmentSettingsViewController: OptionsViewControllerDelegate { } } + + +// MARK: - Feature Flags Toggles + +extension DevelopmentSettingsViewController { + @objc private func toggleLeakProtectionFlag(_ sender: UISwitch) { + AppPreferences.shared.showLeakProtection = sender.isOn + } + + @objc private func toggleLeakProtectionNotificationsFlag(_ sender: UISwitch) { + AppPreferences.shared.showLeakProtectionNotifications = sender.isOn + } + + @objc private func toggleDynamicIslandLiveActivityFlag(_ sender: UISwitch) { + AppPreferences.shared.showDynamicIslandLiveActivity = sender.isOn + } + + private func addFeatureFlagsTogglesActions() { + switchLeakProtectionFlag.addTarget(self, action: #selector(toggleLeakProtectionFlag(_:)), for: .valueChanged) + switchLeakProtectionNotificationsFlag.addTarget(self, action: #selector(toggleLeakProtectionNotificationsFlag(_:)), for: .valueChanged) + switchDynamicIslandLiveActivityFlag.addTarget(self, action: #selector(toggleDynamicIslandLiveActivityFlag(_:)), for: .valueChanged) + + // Additional Feature Flags toggles actions here + } +} diff --git a/PIA VPN/Settings/HelpSettingsViewController.swift b/PIA VPN/Settings/HelpSettingsViewController.swift index c02b7109c..538645e01 100644 --- a/PIA VPN/Settings/HelpSettingsViewController.swift +++ b/PIA VPN/Settings/HelpSettingsViewController.swift @@ -57,7 +57,7 @@ class HelpSettingsViewController: PIABaseSettingsViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - styleNavigationBarWithTitle(L10n.Settings.Section.help) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Section.help) } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { @@ -79,14 +79,16 @@ class HelpSettingsViewController: PIABaseSettingsViewController { @objc private func toggleShareServiceQualityData(_ sender: UISwitch) { let preferences = Client.preferences.editable() preferences.shareServiceQualityData = sender.isOn - preferences.commit() if sender.isOn { + preferences.versionWhenServiceQualityOpted = Macros.versionString() ServiceQualityManager.shared.start() } else { + preferences.versionWhenServiceQualityOpted = nil ServiceQualityManager.shared.stop() } + preferences.commit() reloadSettings() } @@ -95,7 +97,7 @@ class HelpSettingsViewController: PIABaseSettingsViewController { override func viewShouldRestyle() { super.viewShouldRestyle() - styleNavigationBarWithTitle(L10n.Settings.Section.help) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Section.help) // XXX: for some reason, UITableView is not affected by appearance updates if let viewContainer = viewContainer { Theme.current.applyPrincipalBackground(view) @@ -128,7 +130,7 @@ extension HelpSettingsViewController: UITableViewDelegate, UITableViewDataSource switch section { case HelpSections.sendDebugLogs.rawValue: - cell.textLabel?.text = L10n.Settings.Log.information + cell.textLabel?.text = L10n.Localizable.Settings.Log.information case HelpSections.kpiShareStatistics.rawValue: configureShareDataFooterCell(cell) default: @@ -219,9 +221,9 @@ extension HelpSettingsViewController: UITableViewDelegate, UITableViewDataSource private func setupShareDataInformationLabel(_ label: UILabel?) { let attributedString = NSMutableAttributedString() - let description = L10n.Settings.Service.Quality.Share.description + let description = L10n.Localizable.Settings.Service.Quality.Share.description let carriageReturn = "\n" - let findOutMore = L10n.Settings.Service.Quality.Share.findoutmore + let findOutMore = L10n.Localizable.Settings.Service.Quality.Share.findoutmore attributedString.append(NSAttributedString(string: description+carriageReturn, attributes: [.underlineStyle: 0])) attributedString.append(NSAttributedString(string: findOutMore, @@ -230,7 +232,7 @@ extension HelpSettingsViewController: UITableViewDelegate, UITableViewDataSource } @objc private func showShareDataInformation() { - let storyboard = UIStoryboard(name: "Signup", bundle: Bundle(for: ShareDataInformationViewController.self)) + let storyboard = Client.signupStoryboard() let shareDataInformationViewController = storyboard.instantiateViewController(withIdentifier: ViewControllerIdentifiers.shareDataInformation) presentModally(viewController: shareDataInformationViewController) } @@ -265,23 +267,23 @@ extension HelpSettingsViewController: UITableViewDelegate, UITableViewDataSource defer { let alert = Macros.alert(title, message) - alert.addDefaultAction(L10n.Global.ok) + alert.addDefaultAction(L10n.Localizable.Global.ok) self.present(alert, animated: true, completion: nil) } guard let reportId = reportIdentifier else { - title = L10n.Settings.ApplicationInformation.Debug.Failure.title - message = L10n.Settings.ApplicationInformation.Debug.Failure.message + title = L10n.Localizable.Settings.ApplicationInformation.Debug.Failure.title + message = L10n.Localizable.Settings.ApplicationInformation.Debug.Failure.message return } guard !reportId.isEmpty else { - title = L10n.Settings.ApplicationInformation.Debug.Empty.title - message = L10n.Settings.ApplicationInformation.Debug.Empty.message + title = L10n.Localizable.Settings.ApplicationInformation.Debug.Empty.title + message = L10n.Localizable.Settings.ApplicationInformation.Debug.Empty.message return } - title = L10n.Settings.ApplicationInformation.Debug.Success.title - message = L10n.Settings.ApplicationInformation.Debug.Success.message(reportId) + title = L10n.Localizable.Settings.ApplicationInformation.Debug.Success.title + message = L10n.Localizable.Settings.ApplicationInformation.Debug.Success.message(reportId) } } diff --git a/PIA VPN/Settings/NetworkSettingsViewController.swift b/PIA VPN/Settings/NetworkSettingsViewController.swift index 6deea4a3b..d68112541 100644 --- a/PIA VPN/Settings/NetworkSettingsViewController.swift +++ b/PIA VPN/Settings/NetworkSettingsViewController.swift @@ -23,7 +23,8 @@ import UIKit import Popover import SwiftyBeaver import PIALibrary -import TunnelKit +import TunnelKitCore +import TunnelKitOpenVPN import PIAWireguard protocol DNSSettingsDelegate: AnyObject { @@ -38,7 +39,7 @@ class NetworkSettingsViewController: PIABaseSettingsViewController { private var controller: OptionsViewController? private static let DNS: String = "DNS" - private lazy var imvSelectedOption = UIImageView(image: Asset.accessorySelected.image) + private lazy var imvSelectedOption = UIImageView(image: Asset.Images.accessorySelected.image) override func viewDidLoad() { @@ -60,7 +61,7 @@ class NetworkSettingsViewController: PIABaseSettingsViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - styleNavigationBarWithTitle(L10n.Settings.Section.network) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Section.network) } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { @@ -92,7 +93,7 @@ class NetworkSettingsViewController: PIABaseSettingsViewController { override func viewShouldRestyle() { super.viewShouldRestyle() - styleNavigationBarWithTitle(L10n.Settings.Section.network) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Section.network) // XXX: for some reason, UITableView is not affected by appearance updates if let viewContainer = viewContainer { Theme.current.applyPrincipalBackground(view) @@ -202,7 +203,7 @@ extension NetworkSettingsViewController: UITableViewDelegate, UITableViewDataSou if key == (pendingPreferences.vpnType == PIATunnelProfile.vpnType ? DNSList.CUSTOM_OPENVPN_DNS_KEY : DNSList.CUSTOM_WIREGUARD_DNS_KEY) { if !value.isEmpty { controller?.navigationItem.rightBarButtonItem = UIBarButtonItem( - title: L10n.Global.edit, + title: L10n.Localizable.Global.edit, style: .plain, target: self, action: #selector(edit(_:)) @@ -356,12 +357,12 @@ extension NetworkSettingsViewController: OptionsViewControllerDelegate { } if !isFound && option == (pendingPreferences.vpnType == PIATunnelProfile.vpnType ? DNSList.CUSTOM_OPENVPN_DNS_KEY : DNSList.CUSTOM_WIREGUARD_DNS_KEY) { - let alertController = Macros.alert(L10n.Settings.Dns.Custom.dns, - L10n.Settings.Dns.Alert.Create.message) - alertController.addActionWithTitle(L10n.Global.ok) { + let alertController = Macros.alert(L10n.Localizable.Settings.Dns.Custom.dns, + L10n.Localizable.Settings.Dns.Alert.Create.message) + alertController.addActionWithTitle(L10n.Localizable.Global.ok) { self.perform(segue: StoryboardSegue.Main.customDNSSegueIdentifier) } - alertController.addCancelAction(L10n.Global.cancel) + alertController.addCancelAction(L10n.Localizable.Global.cancel) self.present(alertController, animated: true, completion: nil) diff --git a/PIA VPN/Settings/PIABaseSettingsViewController.swift b/PIA VPN/Settings/PIABaseSettingsViewController.swift index 960423357..33e3c9a31 100644 --- a/PIA VPN/Settings/PIABaseSettingsViewController.swift +++ b/PIA VPN/Settings/PIABaseSettingsViewController.swift @@ -21,7 +21,8 @@ import UIKit import PIALibrary -import TunnelKit +import TunnelKitCore +import TunnelKitOpenVPN class PIABaseSettingsViewController: AutolayoutViewController { diff --git a/PIA VPN/Settings/PrivacyFeaturesSettingsViewController.swift b/PIA VPN/Settings/PrivacyFeaturesSettingsViewController.swift index a4d465dff..dc6e4d7cc 100644 --- a/PIA VPN/Settings/PrivacyFeaturesSettingsViewController.swift +++ b/PIA VPN/Settings/PrivacyFeaturesSettingsViewController.swift @@ -31,11 +31,29 @@ class PrivacyFeaturesSettingsViewController: PIABaseSettingsViewController { @IBOutlet weak var tableView: UITableView! private lazy var switchPersistent = UISwitch() private lazy var switchContentBlocker = UISwitch() + private lazy var switchLeakProtection = UISwitch() + private lazy var switchAllowDevicesOnLocalNetwork = UISwitch() private var isContentBlockerEnabled = false + + private var preferences: AppPreferences? + private var sections = [PrivacyFeaturesSections]() + private var vpnProvider: VPNProvider? override func viewDidLoad() { super.viewDidLoad() + preferences = AppPreferences.shared + vpnProvider = Client.providers.vpnProvider + + // Show Leak protection settings when: + // - The feature flag is ON (`showLeakProtection`) + // - Wireguard or OpenVPN is NOT selected + if let preferences = preferences, preferences.showLeakProtection, + !isCurrentProtocolWireguardOrOpenVPN() { + sections = PrivacyFeaturesSections.all() + } else { + sections = PrivacyFeaturesSections.all().filter { $0 != .leakProtection && $0 != .allowAccessOnLocalNetwork } + } tableView.sectionFooterHeight = UITableView.automaticDimension tableView.estimatedSectionFooterHeight = 1.0 @@ -45,6 +63,8 @@ class PrivacyFeaturesSettingsViewController: PIABaseSettingsViewController { switchPersistent.addTarget(self, action: #selector(togglePersistentConnection(_:)), for: .valueChanged) switchContentBlocker.addTarget(self, action: #selector(showContentBlockerTutorial), for: .touchUpInside) + switchLeakProtection.addTarget(self, action: #selector(toggleLeakProtection(_:)), for: .valueChanged) + switchAllowDevicesOnLocalNetwork.addTarget(self, action: #selector(toggleAllowDevicesOnLocalNetwork(_:)), for: .valueChanged) NotificationCenter.default.addObserver(self, selector: #selector(reloadSettings), name: .PIASettingsHaveChanged, object: nil) NotificationCenter.default.addObserver(self, @@ -63,7 +83,7 @@ class PrivacyFeaturesSettingsViewController: PIABaseSettingsViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) refreshContentBlockerState() - styleNavigationBarWithTitle(L10n.Settings.Section.privacyFeatures) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Section.privacyFeatures) } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { @@ -83,9 +103,9 @@ class PrivacyFeaturesSettingsViewController: PIABaseSettingsViewController { @objc private func togglePersistentConnection(_ sender: UISwitch) { if !sender.isOn, Client.preferences.nmtRulesEnabled { - let alert = Macros.alert(nil, L10n.Settings.Nmt.Killswitch.disabled) - alert.addCancelAction(L10n.Global.close) - alert.addActionWithTitle(L10n.Global.enable) { [weak self] in + let alert = Macros.alert(nil, L10n.Localizable.Settings.Nmt.Killswitch.disabled) + alert.addCancelAction(L10n.Localizable.Global.close) + alert.addActionWithTitle(L10n.Localizable.Global.enable) { [weak self] in self?.pendingPreferences.isPersistentConnection = true self?.settingsDelegate.refreshSettings() self?.settingsDelegate.reportUpdatedPreferences() @@ -116,14 +136,34 @@ class PrivacyFeaturesSettingsViewController: PIABaseSettingsViewController { @objc private func showContentBlockerTutorial() { perform(segue: StoryboardSegue.Main.contentBlockerSegueIdentifier) } - + + @objc private func toggleLeakProtection(_ sender: UISwitch) { + Client.preferences.leakProtection = sender.isOn + tableView.reloadData() + presentUpdateSettingsAlertWhenConnected() + } + + @objc private func toggleAllowDevicesOnLocalNetwork(_ sender: UISwitch) { + Client.preferences.allowLocalDeviceAccess = sender.isOn + presentUpdateSettingsAlertWhenConnected() + } + + private func presentUpdateSettingsAlertWhenConnected() { + guard let vpnProvider = vpnProvider, vpnProvider.vpnStatus == .connected else { + return + } + + let sheet = Macros.alertController(L10n.Localizable.Settings.ApplicationSettings.LeakProtection.Alert.title, nil) + sheet.addAction(UIAlertAction(title: L10n.Localizable.Global.ok, style: .default, handler: nil)) + present(sheet, animated: true) + } // MARK: Restylable override func viewShouldRestyle() { super.viewShouldRestyle() - styleNavigationBarWithTitle(L10n.Settings.Section.privacyFeatures) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Section.privacyFeatures) // XXX: for some reason, UITableView is not affected by appearance updates if let viewContainer = viewContainer { Theme.current.applyPrincipalBackground(view) @@ -139,7 +179,7 @@ class PrivacyFeaturesSettingsViewController: PIABaseSettingsViewController { extension PrivacyFeaturesSettingsViewController: UITableViewDelegate, UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { - return PrivacyFeaturesSections.all().count + return sections.count } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { @@ -147,19 +187,38 @@ extension PrivacyFeaturesSettingsViewController: UITableViewDelegate, UITableVie } func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { + guard sections.count > section, + let cell = tableView.dequeueReusableCell(withIdentifier: Cells.footer) else { + return nil + } - if section != PrivacyFeaturesSections.refresh.rawValue, let cell = tableView.dequeueReusableCell(withIdentifier: Cells.footer) { - cell.textLabel?.numberOfLines = 0 - cell.textLabel?.style(style: TextStyle.textStyle21) - cell.backgroundColor = .clear - if section == PrivacyFeaturesSections.killswitch.rawValue { - cell.textLabel?.text = L10n.Settings.ApplicationSettings.KillSwitch.footer - } else { - cell.textLabel?.text = L10n.Settings.ContentBlocker.footer - } + let privacySettingsSection = sections[section] + + cell.textLabel?.numberOfLines = 0 + cell.textLabel?.style(style: TextStyle.textStyle21) + cell.backgroundColor = .clear + + switch privacySettingsSection { + case .killswitch: + cell.textLabel?.text = L10n.Localizable.Settings.ApplicationSettings.KillSwitch.footer + return cell + case .leakProtection: + let leakProtectionDescription = L10n.Localizable.Settings.ApplicationSettings.LeakProtection.footer + let attributtedDescription = NSMutableAttributedString(string: leakProtectionDescription) + let moreInfoText = L10n.Localizable.Settings.ApplicationSettings.LeakProtection.moreInfo + let moreInfoTextRange = (leakProtectionDescription as NSString).range(of: moreInfoText) + attributtedDescription.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: moreInfoTextRange) + cell.textLabel?.attributedText = attributtedDescription + return cell + case .allowAccessOnLocalNetwork: + cell.textLabel?.text = L10n.Localizable.Settings.ApplicationSettings.AllowLocalNetwork.footer return cell + case .safariContentBlocker: + cell.textLabel?.text = L10n.Localizable.Settings.ContentBlocker.footer + return cell + case .refresh: + return nil } - return nil } @@ -170,26 +229,37 @@ extension PrivacyFeaturesSettingsViewController: UITableViewDelegate, UITableVie cell.selectionStyle = .default cell.detailTextLabel?.text = nil - let section = PrivacyFeaturesSections.all()[indexPath.section] + let section = sections[indexPath.section] switch section { case .killswitch: - cell.textLabel?.text = L10n.Settings.ApplicationSettings.KillSwitch.title + cell.textLabel?.text = L10n.Localizable.Settings.ApplicationSettings.KillSwitch.title cell.detailTextLabel?.text = nil cell.accessoryView = switchPersistent cell.selectionStyle = .none switchPersistent.isOn = pendingPreferences.isPersistentConnection - - + case .leakProtection: + cell.textLabel?.text = L10n.Localizable.Settings.ApplicationSettings.LeakProtection.title + cell.detailTextLabel?.text = nil + cell.accessoryView = switchLeakProtection + cell.selectionStyle = .none + switchLeakProtection.isOn = Client.preferences.leakProtection + case .allowAccessOnLocalNetwork: + cell.textLabel?.text = L10n.Localizable.Settings.ApplicationSettings.AllowLocalNetwork.title + cell.detailTextLabel?.text = nil + cell.accessoryView = switchAllowDevicesOnLocalNetwork + cell.selectionStyle = .none + switchAllowDevicesOnLocalNetwork.isEnabled = Client.preferences.leakProtection + switchAllowDevicesOnLocalNetwork.isOn = !Client.preferences.leakProtection ? false : Client.preferences.allowLocalDeviceAccess case .safariContentBlocker: - cell.textLabel?.text = L10n.Settings.ContentBlocker.title + cell.textLabel?.text = L10n.Localizable.Settings.ContentBlocker.title cell.detailTextLabel?.text = nil cell.accessoryView = switchContentBlocker cell.selectionStyle = .none switchContentBlocker.isOn = isContentBlockerEnabled case .refresh: - cell.textLabel?.text = L10n.Settings.ContentBlocker.Refresh.title + cell.textLabel?.text = L10n.Localizable.Settings.ContentBlocker.Refresh.title cell.detailTextLabel?.text = nil } @@ -214,12 +284,21 @@ extension PrivacyFeaturesSettingsViewController: UITableViewDelegate, UITableVie func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - let section = PrivacyFeaturesSections.all()[indexPath.section] - + let section = sections[indexPath.section] + switch section { - case .refresh: - refreshContentBlockerRules() - default: break + case .refresh: + refreshContentBlockerRules() + case .leakProtection: + let application = UIApplication.shared + let learnMoreURL = AppConstants.Web.leakProtectionURL + + // Open the Learn more url when the user taps on the Leak Protection cell + if application.canOpenURL(learnMoreURL) { + application.open(learnMoreURL) + } + + default: break } tableView.deselectRow(at: indexPath, animated: true) @@ -246,3 +325,21 @@ extension PrivacyFeaturesSettingsViewController: UITableViewDelegate, UITableVie } } + + +extension PrivacyFeaturesSettingsViewController { + func isCurrentProtocolWireguardOrOpenVPN() -> Bool { + + // Selected protocol is OpenVPN + if pendingPreferences.vpnType == PIATunnelProfile.vpnType { + return true + } + + // Selected protocol is Wireguard + if pendingPreferences.vpnType == PIAWGTunnelProfile.vpnType { + return true + } + + return false + } +} diff --git a/PIA VPN/Settings/SettingPopoverSelectionView.swift b/PIA VPN/Settings/SettingPopoverSelectionView.swift index 1734bd0eb..14ce71dc4 100644 --- a/PIA VPN/Settings/SettingPopoverSelectionView.swift +++ b/PIA VPN/Settings/SettingPopoverSelectionView.swift @@ -22,7 +22,8 @@ import UIKit import PIALibrary import Popover -import TunnelKit +import TunnelKitCore +import TunnelKitOpenVPN class SettingPopoverSelectionView: UIView { @@ -110,6 +111,7 @@ extension ProtocolPopoverSelectionView: UITableViewDelegate, UITableViewDataSour let vpnType = protocols[indexPath.row] pendingPreferences.vpnType = vpnType + settingsDelegate.updateSetting(ProtocolsSections.protocolSelection, withValue: nil) Macros.postNotification(.PIASettingsHaveChanged) Macros.postNotification(.RefreshSettings) @@ -149,7 +151,7 @@ extension TransportPopoverSelectionView: UITableViewDelegate, UITableViewDataSou cell.textLabel?.style(style: cellTextStyle) if options[indexPath.row] == ProtocolSettingsViewController.AUTOMATIC_SOCKET { - cell.textLabel?.text = L10n.Global.automatic + cell.textLabel?.text = L10n.Localizable.Global.automatic } else { cell.textLabel?.text = options[indexPath.row] } @@ -207,7 +209,7 @@ extension PortPopoverSelectionView: UITableViewDelegate, UITableViewDataSource { cell.textLabel?.style(style: cellTextStyle) if options[indexPath.row] == ProtocolSettingsViewController.AUTOMATIC_PORT { - cell.textLabel?.text = L10n.Global.automatic + cell.textLabel?.text = L10n.Localizable.Global.automatic } else { cell.textLabel?.text = options[indexPath.row].description } diff --git a/PIA VPN/SettingsDelegate.swift b/PIA VPN/SettingsDelegate.swift index be9293aba..ae1aec848 100644 --- a/PIA VPN/SettingsDelegate.swift +++ b/PIA VPN/SettingsDelegate.swift @@ -21,7 +21,8 @@ import Foundation import PIAWireguard -import TunnelKit +import TunnelKitCore +import TunnelKitOpenVPN protocol SettingsDelegate: AnyObject { diff --git a/PIA VPN/SettingsViewController.swift b/PIA VPN/SettingsViewController.swift index df82a1a1b..5397c261b 100644 --- a/PIA VPN/SettingsViewController.swift +++ b/PIA VPN/SettingsViewController.swift @@ -22,11 +22,13 @@ import UIKit import PIALibrary -import TunnelKit +import TunnelKitCore +import TunnelKitOpenVPN import SafariServices import SwiftyBeaver import PIAWireguard import WidgetKit +import AlamofireImage private let log = SwiftyBeaver.self @@ -91,7 +93,7 @@ class SettingsViewController: AutolayoutViewController, SettingsDelegate { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - styleNavigationBarWithTitle(L10n.Menu.Item.settings) + styleNavigationBarWithTitle(L10n.Localizable.Menu.Item.settings) } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { @@ -204,7 +206,7 @@ class SettingsViewController: AutolayoutViewController, SettingsDelegate { // MARK: Actions @objc private func viewHasRotated() { - styleNavigationBarWithTitle(L10n.Menu.Item.settings) + styleNavigationBarWithTitle(L10n.Localizable.Menu.Item.settings) } @objc func refreshSettings() { @@ -228,13 +230,13 @@ class SettingsViewController: AutolayoutViewController, SettingsDelegate { func resetToDefaultSettings() { let alert = Macros.alert( - L10n.Settings.Reset.Defaults.Confirm.title, - L10n.Settings.Reset.Defaults.Confirm.message + L10n.Localizable.Settings.Reset.Defaults.Confirm.title, + L10n.Localizable.Settings.Reset.Defaults.Confirm.message ) - alert.addDestructiveActionWithTitle(L10n.Settings.Reset.Defaults.Confirm.button) { + alert.addDestructiveActionWithTitle(L10n.Localizable.Settings.Reset.Defaults.Confirm.button) { self.doReset() } - alert.addCancelAction(L10n.Global.cancel) + alert.addCancelAction(L10n.Localizable.Global.cancel) self.present(alert, animated: true, completion: nil) } @@ -264,7 +266,7 @@ class SettingsViewController: AutolayoutViewController, SettingsDelegate { preferences.ikeV2PacketSize = pendingPreferences.ikeV2PacketSize preferences.commit() - guard let currentOpenVPNConfiguration = pendingPreferences.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNTunnelProvider.Configuration else { + guard let currentOpenVPNConfiguration = pendingPreferences.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNProvider.Configuration else { fatalError("No default VPN custom configuration provided for PIA protocol") } AppPreferences.shared.reset() @@ -330,17 +332,17 @@ class SettingsViewController: AutolayoutViewController, SettingsDelegate { guard action.canRetainConnection else { let alert = Macros.alert( title, - L10n.Settings.Commit.Messages.mustDisconnect + L10n.Localizable.Settings.Commit.Messages.mustDisconnect ) // reconnect -> reconnect VPN and close - alert.addActionWithTitle(L10n.Settings.Commit.Buttons.reconnect) { + alert.addActionWithTitle(L10n.Localizable.Settings.Commit.Buttons.reconnect) { self.commitPreferences() completionHandlerAfterVPNAction(true) } // cancel -> revert changes and close - alert.addCancelActionWithTitle(L10n.Global.cancel) { + alert.addCancelActionWithTitle(L10n.Localizable.Global.cancel) { completionHandler() } present(alert, animated: true, completion: nil) @@ -353,16 +355,16 @@ class SettingsViewController: AutolayoutViewController, SettingsDelegate { let alert = Macros.alert( title, - L10n.Settings.Commit.Messages.shouldReconnect + L10n.Localizable.Settings.Commit.Messages.shouldReconnect ) // reconnect -> reconnect VPN and close - alert.addActionWithTitle(L10n.Settings.Commit.Buttons.reconnect) { + alert.addActionWithTitle(L10n.Localizable.Settings.Commit.Buttons.reconnect) { completionHandlerAfterVPNAction(true) } // later -> close - alert.addCancelActionWithTitle(L10n.Settings.Commit.Buttons.later) { + alert.addCancelActionWithTitle(L10n.Localizable.Settings.Commit.Buttons.later) { completionHandler() } @@ -412,8 +414,8 @@ class SettingsViewController: AutolayoutViewController, SettingsDelegate { @objc func reloadSettings() { pendingPreferences = Client.preferences.editable() - guard let currentOpenVPNConfiguration = pendingPreferences.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNTunnelProvider.Configuration ?? - Client.preferences.defaults.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNTunnelProvider.Configuration else { + guard let currentOpenVPNConfiguration = pendingPreferences.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNProvider.Configuration ?? + Client.preferences.defaults.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNProvider.Configuration else { fatalError("No default VPN custom configuration provided for PIA OpenVPN protocol") } @@ -439,7 +441,7 @@ class SettingsViewController: AutolayoutViewController, SettingsDelegate { log.debug("OpenVPN endpoints: \(pendingOpenVPNConfiguration.endpointProtocols ?? [])") if pendingPreferences.vpnType == PIATunnelProfile.vpnType { - var builder = OpenVPNTunnelProvider.ConfigurationBuilder(sessionConfiguration: pendingOpenVPNConfiguration.build()) + var builder = OpenVPNProvider.ConfigurationBuilder(sessionConfiguration: pendingOpenVPNConfiguration.build()) if pendingPreferences.vpnType == PIATunnelProfile.vpnType { if AppPreferences.shared.useSmallPackets { @@ -460,10 +462,24 @@ class SettingsViewController: AutolayoutViewController, SettingsDelegate { } } + updateCustomDNSAppPreferences() refreshSettings() reportUpdatedPreferences() } + private func updateCustomDNSAppPreferences() { + var dnsServers = pendingOpenVPNConfiguration.dnsServers + if pendingPreferences.vpnType == PIAWGTunnelProfile.vpnType { + dnsServers = pendingWireguardVPNConfiguration.customDNSServers + } + + if let dnsServers = dnsServers { + AppPreferences.shared.usesCustomDNS = DNSList.shared.hasCustomDNS(for: pendingPreferences.vpnType, in: dnsServers) + } else { + AppPreferences.shared.usesCustomDNS = false + } + } + // MARK: ModalController override func dismissModal() { @@ -478,7 +494,7 @@ class SettingsViewController: AutolayoutViewController, SettingsDelegate { override func viewShouldRestyle() { super.viewShouldRestyle() - styleNavigationBarWithTitle(L10n.Menu.Item.settings) + styleNavigationBarWithTitle(L10n.Localizable.Menu.Item.settings) // XXX: for some reason, UITableView is not affected by appearance updates if let viewContainer = viewContainer { Theme.current.applyPrincipalBackground(view) @@ -566,7 +582,7 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { switch section { case .automation: - cell.detailTextLabel?.text = Client.preferences.nmtRulesEnabled ? L10n.Global.enabled : L10n.Global.disabled + cell.detailTextLabel?.text = Client.preferences.nmtRulesEnabled ? L10n.Localizable.Global.enabled : L10n.Localizable.Global.disabled case .protocols: cell.detailTextLabel?.text = pendingPreferences?.vpnType.vpnProtocol default: break diff --git a/PIA VPN/ShareDataInformationViewController.swift b/PIA VPN/ShareDataInformationViewController.swift new file mode 100644 index 000000000..8ee63ebbe --- /dev/null +++ b/PIA VPN/ShareDataInformationViewController.swift @@ -0,0 +1,37 @@ +// +// ShareDataInformationViewController.swift +// PIALibrary +// +// Created by Miguel Berrocal on 17/6/21. +// + + +import Foundation +import UIKit + +public class ShareDataInformationViewController: AutolayoutViewController { + + @IBOutlet private weak var labelInformation: UILabel! + + @IBOutlet private weak var contentView: UIView! + @IBOutlet private weak var closeButton: UIButton! + + public override func viewDidLoad() { + super.viewDidLoad() + + self.labelInformation.text = L10n.Signup.Share.Data.ReadMore.Text.description + } + + // MARK: Restylable + + public override func viewShouldRestyle() { + super.viewShouldRestyle() + Theme.current.applyPrincipalBackground(contentView) + Theme.current.applySubtitle(labelInformation) + } + + @IBAction private func close() { + dismissModal() + } + +} diff --git a/PIA VPN/ShowConnectionStatsViewController.swift b/PIA VPN/ShowConnectionStatsViewController.swift index cb697bc11..b3de820c4 100644 --- a/PIA VPN/ShowConnectionStatsViewController.swift +++ b/PIA VPN/ShowConnectionStatsViewController.swift @@ -21,6 +21,7 @@ import Foundation import PIALibrary +import UIKit class ShowConnectionStatsViewController: AutolayoutViewController { @@ -60,7 +61,7 @@ class ShowConnectionStatsViewController: AutolayoutViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - styleNavigationBarWithTitle(L10n.Settings.Service.Quality.Show.title) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Service.Quality.Show.title) } override func viewDidLayoutSubviews() { @@ -76,7 +77,7 @@ class ShowConnectionStatsViewController: AutolayoutViewController { // MARK: Helpers @objc private func viewHasRotated() { - styleNavigationBarWithTitle(L10n.Settings.Service.Quality.Show.title) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Service.Quality.Show.title) } // MARK: Restylable @@ -84,7 +85,7 @@ class ShowConnectionStatsViewController: AutolayoutViewController { override func viewShouldRestyle() { super.viewShouldRestyle() - styleNavigationBarWithTitle(L10n.Settings.Service.Quality.Show.title) + styleNavigationBarWithTitle(L10n.Localizable.Settings.Service.Quality.Show.title) // XXX: for some reason, UITableView is not affected by appearance updates if let viewContainer = viewContainer { Theme.current.applyPrincipalBackground(view) diff --git a/PIA VPN/ShowQuickSettingsViewController.swift b/PIA VPN/ShowQuickSettingsViewController.swift index d5825226a..830353f03 100644 --- a/PIA VPN/ShowQuickSettingsViewController.swift +++ b/PIA VPN/ShowQuickSettingsViewController.swift @@ -72,11 +72,11 @@ class ShowQuickSettingsViewController: AutolayoutViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - styleNavigationBarWithTitle(L10n.Tiles.Quicksettings.title) + styleNavigationBarWithTitle(L10n.Localizable.Tiles.Quicksettings.title) } @objc private func viewHasRotated() { - styleNavigationBarWithTitle(L10n.Tiles.Quicksettings.title) + styleNavigationBarWithTitle(L10n.Localizable.Tiles.Quicksettings.title) } // MARK: Switch actions @@ -123,10 +123,10 @@ class ShowQuickSettingsViewController: AutolayoutViewController { private func cancelDisablingAction() { tableView.reloadData() let alert = Macros.alert( - L10n.Tiles.Quicksettings.title, - L10n.Tiles.Quicksettings.Min.Elements.message + L10n.Localizable.Tiles.Quicksettings.title, + L10n.Localizable.Tiles.Quicksettings.Min.Elements.message ) - alert.addActionWithTitle(L10n.Global.ok) { + alert.addActionWithTitle(L10n.Localizable.Global.ok) { } present(alert, animated: true, completion: nil) } @@ -143,7 +143,7 @@ class ShowQuickSettingsViewController: AutolayoutViewController { override func viewShouldRestyle() { super.viewShouldRestyle() - styleNavigationBarWithTitle(L10n.Tiles.Quicksettings.title) + styleNavigationBarWithTitle(L10n.Localizable.Tiles.Quicksettings.title) // XXX: for some reason, UITableView is not affected by appearance updates if let viewContainer = viewContainer { @@ -183,32 +183,32 @@ extension ShowQuickSettingsViewController: UITableViewDataSource, UITableViewDel let option = options[indexPath.row] switch option { case .theme: - cell.titleLabel.text = L10n.Settings.ApplicationSettings.ActiveTheme.title + cell.titleLabel.text = L10n.Localizable.Settings.ApplicationSettings.ActiveTheme.title cell.accessoryView = switchThemeSettings - cell.settingImage.image = Theme.current.palette.appearance == .light ? Asset.Piax.Global.themeLightInactive.image : - Asset.Piax.Global.themeDarkInactive.image - cell.settingImage.accessibilityLabel = L10n.Settings.ApplicationSettings.ActiveTheme.title + cell.settingImage.image = Theme.current.palette.appearance == .light ? Asset.Images.Piax.Global.themeLightInactive.image : + Asset.Images.Piax.Global.themeDarkInactive.image + cell.settingImage.accessibilityLabel = L10n.Localizable.Settings.ApplicationSettings.ActiveTheme.title switchThemeSettings.isOn = AppPreferences.shared.quickSettingThemeVisible case .killswitch: - cell.titleLabel.text = L10n.Settings.ApplicationSettings.KillSwitch.title + cell.titleLabel.text = L10n.Localizable.Settings.ApplicationSettings.KillSwitch.title cell.accessoryView = switchKillSwitchSetting - cell.settingImage.image = Theme.current.palette.appearance == .light ? Asset.Piax.Global.killswitchLightInactive.image : - Asset.Piax.Global.killswitchDarkInactive.image - cell.settingImage.accessibilityLabel = L10n.Settings.ApplicationSettings.KillSwitch.title + cell.settingImage.image = Theme.current.palette.appearance == .light ? Asset.Images.Piax.Global.killswitchLightInactive.image : + Asset.Images.Piax.Global.killswitchDarkInactive.image + cell.settingImage.accessibilityLabel = L10n.Localizable.Settings.ApplicationSettings.KillSwitch.title switchKillSwitchSetting.isOn = AppPreferences.shared.quickSettingKillswitchVisible case .networkTools: - cell.titleLabel.text = L10n.Tiles.Quicksetting.Nmt.title + cell.titleLabel.text = L10n.Localizable.Tiles.Quicksetting.Nmt.title cell.accessoryView = switchNetworkToolsSetting - cell.settingImage.image = Theme.current.palette.appearance == .light ? Asset.Piax.Global.nmtLightInactive.image : - Asset.Piax.Global.nmtDarkInactive.image - cell.settingImage.accessibilityLabel = L10n.Tiles.Quicksetting.Nmt.title + cell.settingImage.image = Theme.current.palette.appearance == .light ? Asset.Images.Piax.Global.nmtLightInactive.image : + Asset.Images.Piax.Global.nmtDarkInactive.image + cell.settingImage.accessibilityLabel = L10n.Localizable.Tiles.Quicksetting.Nmt.title switchNetworkToolsSetting.isOn = AppPreferences.shared.quickSettingNetworkToolVisible case .privateBrowsing: - cell.titleLabel.text = L10n.Tiles.Quicksetting.Private.Browser.title + cell.titleLabel.text = L10n.Localizable.Tiles.Quicksetting.Private.Browser.title cell.accessoryView = switchPrivateBrowserSetting - cell.settingImage.image = Theme.current.palette.appearance == .light ? Asset.Piax.Global.browserLightInactive.image : - Asset.Piax.Global.browserDarkInactive.image - cell.settingImage.accessibilityLabel = L10n.Tiles.Quicksetting.Private.Browser.title + cell.settingImage.image = Theme.current.palette.appearance == .light ? Asset.Images.Piax.Global.browserLightInactive.image : + Asset.Images.Piax.Global.browserDarkInactive.image + cell.settingImage.accessibilityLabel = L10n.Localizable.Tiles.Quicksetting.Private.Browser.title switchPrivateBrowserSetting.isOn = AppPreferences.shared.quickSettingPrivateBrowserVisible } Theme.current.applySettingsCellTitle(cell.titleLabel, diff --git a/PIA VPN/SignupFailureViewController.swift b/PIA VPN/SignupFailureViewController.swift new file mode 100644 index 000000000..1a8575d6b --- /dev/null +++ b/PIA VPN/SignupFailureViewController.swift @@ -0,0 +1,91 @@ +// +// SignupFailureViewController.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/8/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import PIALibrary + +public class SignupFailureViewController: AutolayoutViewController, BrandableNavigationBar { + + @IBOutlet private weak var imvPicture: UIImageView! + @IBOutlet private weak var labelTitle: UILabel! + @IBOutlet private weak var labelMessage: UILabel! + @IBOutlet private weak var buttonSubmit: PIAButton! + + var error: Error? + + override public func viewDidLoad() { + super.viewDidLoad() + + navigationItem.hidesBackButton = true + + title = L10n.Signup.Failure.vcTitle + imvPicture.image = Asset.Ui.imageAccountFailed.image + labelTitle.text = L10n.Signup.Failure.title + labelMessage.text = L10n.Signup.Failure.message + + if let clientError = error as? ClientError { + switch clientError { + case .redeemInvalid: + title = L10n.Welcome.Redeem.title + imvPicture.image = Asset.Ui.imageRedeemInvalid.image + labelTitle.text = L10n.Signup.Failure.Redeem.Invalid.title + labelMessage.text = L10n.Signup.Failure.Redeem.Invalid.message + break + case .redeemClaimed: + title = L10n.Welcome.Redeem.title + imvPicture.image = Asset.Ui.imageRedeemClaimed.image + labelTitle.text = L10n.Signup.Failure.Redeem.Claimed.title + labelMessage.text = L10n.Signup.Failure.Redeem.Claimed.message + break + + default: + break + } + } + + self.styleSubmitButton() + } + + @IBAction private func submit() { + dismissModal() + } + + // MARK: Restylable + + override public func viewShouldRestyle() { + super.viewShouldRestyle() + navigationItem.titleView = NavigationLogoView() + Theme.current.applyNavigationBarStyle(to: self) + Theme.current.applyPrincipalBackground(view) + Theme.current.applyPrincipalBackground(viewContainer!) + Theme.current.applySubtitle(labelMessage) + Theme.current.applyTitle(labelTitle, appearance: .dark) + } + + private func styleSubmitButton() { + buttonSubmit.setRounded() + buttonSubmit.style(style: TextStyle.Buttons.piaGreenButton) + buttonSubmit.setTitle(L10n.Signup.Failure.submit.uppercased(), + for: []) + } + +} diff --git a/PIA VPN/SignupInProgressViewController.swift b/PIA VPN/SignupInProgressViewController.swift new file mode 100644 index 000000000..368d7e503 --- /dev/null +++ b/PIA VPN/SignupInProgressViewController.swift @@ -0,0 +1,151 @@ +// +// SignupInProgressViewController.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/8/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import SwiftyBeaver +import PIALibrary + +private let log = SwiftyBeaver.self + +public class SignupInProgressViewController: AutolayoutViewController, BrandableNavigationBar { + @IBOutlet private weak var progressView: CircleProgressView! + + @IBOutlet private weak var titleMessage: UILabel! + @IBOutlet private weak var labelMessage: UILabel! + + var signupRequest: SignupRequest? + + var redeemRequest: RedeemRequest? + + var preset: Preset? + + var metadata: SignupMetadata? + + weak var completionDelegate: WelcomeCompletionDelegate? + + private var user: UserAccount? + + private var error: Error? + + override public func viewDidLoad() { + super.viewDidLoad() + + labelMessage.text = metadata?.bodySubtitle + titleMessage.text = metadata?.title + } + + override public func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + progressView.startAnimating() + + if let request = signupRequest { + performSignup(with: request) + } + } + + private func performSignup(with request: SignupRequest) { + log.debug("Signing up...") + + preset?.accountProvider.signup(with: request) { (user, error) in + guard let user = user else { + self.user = nil + self.error = error + if let clientError = error as? ClientError, (clientError == .internetUnreachable) { + log.error("Failed to sign up: Internet is unreachable") + self.perform(segue: StoryboardSegue.Signup.internetUnreachableSegueIdentifier, sender: nil) + return + } + if let error = error { + log.error("Failed to sign up (error: \(error))") + } else { + log.error("Failed to sign up") + } + self.perform(segue: StoryboardSegue.Signup.failureSegueIdentifier) + return + } + + log.debug("Sign-up succeeded!") + + self.user = user + self.error = nil + self.perform(segue: StoryboardSegue.Signup.successSegueIdentifier) + } + } + + override public func prepare(for segue: UIStoryboardSegue, sender: Any?) { + guard let identifier = segue.identifier, let segueType = StoryboardSegue.Signup(rawValue: identifier) else { + return + } + switch segueType { + case .successSegueIdentifier: + + guard let email = signupRequest?.email ?? redeemRequest?.email else { + fatalError("Email not provided with signup or redeem request") + } + + let vc = segue.destination as! ConfirmVPNPlanViewController + var metadata = SignupMetadata(email: email, user: user) + if let _ = signupRequest { + metadata.title = L10n.Signup.InProgress.title + metadata.bodyImage = Asset.Images.imagePurchaseSuccess.image + metadata.bodyTitle = L10n.Signup.Success.title + metadata.bodySubtitle = L10n.Signup.Success.messageFormat(metadata.email) + } else if let _ = redeemRequest { + metadata.title = L10n.Welcome.Redeem.title + metadata.bodyImage = Asset.Ui.imageRedeemSuccess.image + metadata.bodyImageOffset = CGPoint(x: -10.0, y: 0.0) + metadata.bodyTitle = L10n.Signup.Success.Redeem.title + metadata.bodySubtitle = L10n.Signup.Success.Redeem.message + } + vc.preset = preset + vc.metadata = metadata + vc.completionDelegate = completionDelegate + + case .failureSegueIdentifier: + let vc = segue.destination as! SignupFailureViewController + vc.error = error + break + + default: + break + } + } + + // MARK: Unwind + + @IBAction private func unwoundSignupInternetUnreachable(segue: UIStoryboardSegue) { + } + + // MARK: Restylable + + override public func viewShouldRestyle() { + super.viewShouldRestyle() + navigationItem.titleView = NavigationLogoView() + Theme.current.applyNavigationBarStyle(to: self) + Theme.current.applyPrincipalBackground(view) + Theme.current.applyPrincipalBackground(viewContainer!) + Theme.current.applyTitle(titleMessage, appearance: .dark) + Theme.current.applySubtitle(labelMessage) + Theme.current.applyCircleProgressView(progressView) + } +} diff --git a/PIA VPN/SignupInternetUnreachableViewController.swift b/PIA VPN/SignupInternetUnreachableViewController.swift new file mode 100644 index 000000000..9ce1cf3c8 --- /dev/null +++ b/PIA VPN/SignupInternetUnreachableViewController.swift @@ -0,0 +1,69 @@ +// +// SignupUnreachableViewController.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/8/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import PIALibrary + +public class SignupUnreachableViewController: AutolayoutViewController, BrandableNavigationBar { + + @IBOutlet private weak var imvPicture: UIImageView! + @IBOutlet private weak var labelTitle: UILabel! + @IBOutlet private weak var labelMessage: UILabel! + @IBOutlet private weak var buttonSubmit: PIAButton! + + override public func viewDidLoad() { + super.viewDidLoad() + + navigationItem.hidesBackButton = true + + title = L10n.Signup.Unreachable.vcTitle + imvPicture.image = Asset.Ui.imageNoInternet.image + labelTitle.text = L10n.Signup.Unreachable.title + labelMessage.text = L10n.Signup.Unreachable.message + self.styleSubmitButton() + + } + + @IBAction private func submit() { + perform(segue: StoryboardSegue.Signup.unwindInternetUnreachableSegueIdentifier) + } + + // MARK: Restylable + + override public func viewShouldRestyle() { + super.viewShouldRestyle() + navigationItem.titleView = NavigationLogoView() + Theme.current.applyNavigationBarStyle(to: self) + Theme.current.applyPrincipalBackground(view) + Theme.current.applyPrincipalBackground(viewContainer!) + Theme.current.applySubtitle(labelMessage) + Theme.current.applyTitle(labelTitle, appearance: .dark) + } + + private func styleSubmitButton() { + buttonSubmit.setRounded() + buttonSubmit.style(style: TextStyle.Buttons.piaGreenButton) + buttonSubmit.setTitle(L10n.Signup.Unreachable.submit.uppercased(), + for: []) + } + +} diff --git a/PIA VPN/SignupSuccessViewController.swift b/PIA VPN/SignupSuccessViewController.swift new file mode 100644 index 000000000..6c8ea624b --- /dev/null +++ b/PIA VPN/SignupSuccessViewController.swift @@ -0,0 +1,182 @@ +// +// SignupSuccessViewController.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/8/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import Foundation +import SwiftyBeaver +import UIKit +import PIALibrary + +private let log = SwiftyBeaver.self + +public class SignupSuccessViewController: AutolayoutViewController, BrandableNavigationBar { + + @IBOutlet private weak var imvPicture: UIImageView! + @IBOutlet private weak var labelTitle: UILabel! + @IBOutlet private weak var labelMessage: UILabel! + @IBOutlet private weak var labelUsernameCaption: UILabel! + @IBOutlet private weak var labelUsername: UILabel! + @IBOutlet private weak var labelPasswordCaption: UILabel! + @IBOutlet private weak var labelPassword: UILabel! + @IBOutlet private weak var buttonSubmit: PIAButton! + @IBOutlet private weak var usernameContainer: UIView! + @IBOutlet private weak var passwordContainer: UIView! + + //Share data + @IBOutlet private weak var shareDataContainer: UIView! + @IBOutlet private weak var shareDataImageView: UIImageView! + @IBOutlet private weak var shareDataTitleLabel: UILabel! + @IBOutlet private weak var shareDataDescriptionLabel: UILabel! + @IBOutlet private weak var readMoreButton: PIAButton! + @IBOutlet private weak var acceptButton: PIAButton! + @IBOutlet private weak var cancelButton: PIAButton! + @IBOutlet private weak var shareDataFooterLabel: UILabel! + + @IBOutlet private weak var constraintPictureXOffset: NSLayoutConstraint! + + var metadata: SignupMetadata? + + weak var completionDelegate: WelcomeCompletionDelegate? + + override public func viewDidLoad() { + super.viewDidLoad() + + guard let metadata = metadata else { + fatalError("Metadata not set") + } + + title = metadata.title + imvPicture.image = metadata.bodyImage + if let offset = metadata.bodyImageOffset { + constraintPictureXOffset.constant = offset.x + } + labelTitle.text = metadata.bodyTitle + labelMessage.text = metadata.bodySubtitle + + navigationItem.hidesBackButton = true + + labelUsernameCaption.text = L10n.Signup.Success.Username.caption + labelUsername.text = metadata.user?.credentials.username + labelPasswordCaption.text = L10n.Signup.Success.Password.caption + labelPassword.text = metadata.user?.credentials.password + + self.styleSubmitButton() + self.styleContainers() + + shareDataImageView.image = Asset.Ui.imageDocumentConsent.image + shareDataTitleLabel.text = L10n.Signup.Share.Data.Text.title + shareDataDescriptionLabel.text = L10n.Signup.Share.Data.Text.description + shareDataFooterLabel.text = L10n.Signup.Share.Data.Text.footer + self.styleShareDataButtons() + } + + @IBAction private func submit() { + guard let user = metadata?.user else { + fatalError("User account not set in metadata") + } + completionDelegate?.welcomeDidSignup(withUser: user, topViewController: self) + } + + @IBAction private func acceptShareData() { + let preferences = Client.preferences.editable() + preferences.shareServiceQualityData = true + preferences.versionWhenServiceQualityOpted = Macros.versionString() + preferences.commit() + DispatchQueue.main.async { + UIView.animate(withDuration: 0.3) { + self.shareDataContainer.alpha = 0 + } + } + } + + @IBAction private func rejectShareData() { + let preferences = Client.preferences.editable() + preferences.shareServiceQualityData = false + preferences.versionWhenServiceQualityOpted = nil + preferences.commit() + DispatchQueue.main.async { + UIView.animate(withDuration: 0.3) { + self.shareDataContainer.alpha = 0 + } + } + } + + // MARK: Restylable + + override public func viewShouldRestyle() { + super.viewShouldRestyle() + navigationItem.titleView = NavigationLogoView() + Theme.current.applyNavigationBarStyle(to: self) + Theme.current.applyPrincipalBackground(view) + Theme.current.applyPrincipalBackground(viewContainer!) + Theme.current.applyPrincipalBackground(shareDataContainer!) + + Theme.current.applyTitle(labelTitle, appearance: .dark) + Theme.current.applySubtitle(labelMessage) + + Theme.current.applyTitle(shareDataTitleLabel, appearance: .dark) + Theme.current.applySubtitle(shareDataDescriptionLabel) + Theme.current.applySmallSubtitle(shareDataFooterLabel) + Theme.current.applyTransparentButton(cancelButton, + withSize: 1.0) + Theme.current.applyButtonLabelMediumStyle(acceptButton) + + Theme.current.applySubtitle(labelUsernameCaption) + Theme.current.applyTitle(labelUsername, appearance: .dark) + Theme.current.applySubtitle(labelPasswordCaption) + Theme.current.applyTitle(labelPassword, appearance: .dark) + } + + private func styleSubmitButton() { + buttonSubmit.setRounded() + buttonSubmit.style(style: TextStyle.Buttons.piaGreenButton) + buttonSubmit.setTitle(L10n.Signup.Success.submit.uppercased(), + for: []) + } + + private func styleShareDataButtons() { + acceptButton.setRounded() + acceptButton.style(style: TextStyle.Buttons.piaGreenButton) + acceptButton.setTitle(L10n.Signup.Share.Data.Buttons.accept.uppercased(), + for: []) + cancelButton.setRounded() + cancelButton.style(style: TextStyle.Buttons.piaPlainTextButton) + cancelButton.setTitle(L10n.Signup.Share.Data.Buttons.noThanks.uppercased(), + for: []) + Theme.current.applyTransparentButton(cancelButton, + withSize: 1.0) + readMoreButton.setTitle(L10n.Signup.Share.Data.Buttons.readMore, for: .normal) + Theme.current.applyUnderlinedSubtitleButton(readMoreButton) + } + + private func styleContainers() { + self.styleContainerView(usernameContainer) + self.styleContainerView(passwordContainer) + } + + func styleContainerView(_ view: UIView) { + view.layer.cornerRadius = 6.0 + view.clipsToBounds = true + view.layer.borderWidth = 0.5 + view.layer.borderColor = UIColor.piaGrey4.cgColor + } + +} diff --git a/PIA VPN/Siri/SiriShortcutsBuilder.swift b/PIA VPN/Siri/SiriShortcutsBuilder.swift index 628beb4b9..ec97e8e33 100644 --- a/PIA VPN/Siri/SiriShortcutsBuilder.swift +++ b/PIA VPN/Siri/SiriShortcutsBuilder.swift @@ -52,7 +52,7 @@ extension SiriShortcutBuilder { class SiriShortcutConnect: SiriShortcutBuilder { var activityType = AppConstants.SiriShortcuts.shortcutConnect - var title = L10n.Siri.Shortcuts.Connect.title + var title = L10n.Localizable.Siri.Shortcuts.Connect.title var persistentIdentifier = AppConstants.SiriShortcuts.shortcutConnect } @@ -61,7 +61,7 @@ class SiriShortcutConnect: SiriShortcutBuilder { class SiriShortcutDisconnect: SiriShortcutBuilder { var activityType = AppConstants.SiriShortcuts.shortcutDisconnect - var title = L10n.Siri.Shortcuts.Disconnect.title + var title = L10n.Localizable.Siri.Shortcuts.Disconnect.title var persistentIdentifier = AppConstants.SiriShortcuts.shortcutDisconnect } diff --git a/PIA VPN/Siri/SiriShortcutsManager.swift b/PIA VPN/Siri/SiriShortcutsManager.swift index a5de0c4a0..7af4ecc3e 100644 --- a/PIA VPN/Siri/SiriShortcutsManager.swift +++ b/PIA VPN/Siri/SiriShortcutsManager.swift @@ -70,17 +70,17 @@ public class SiriShortcutsManager: NSObject { func descriptionActionForConnectShortcut() -> String { if AppPreferences.shared.useConnectSiriShortcuts { - return L10n.Global.edit + return L10n.Localizable.Global.edit } else { - return L10n.Global.add + return L10n.Localizable.Global.add } } func descriptionActionForDisconnectShortcut() -> String { if AppPreferences.shared.useDisconnectSiriShortcuts { - return L10n.Global.edit + return L10n.Localizable.Global.edit } else { - return L10n.Global.add + return L10n.Localizable.Global.add } } @@ -95,9 +95,9 @@ extension SiriShortcutsManager: INUIAddVoiceShortcutViewControllerDelegate { error: Error? ) { if let _ = error { - let message = L10n.Siri.Shortcuts.Add.error + let message = L10n.Localizable.Siri.Shortcuts.Add.error let alert = Macros.alert(nil, message) - alert.addCancelActionWithTitle(L10n.Global.cancel) { + alert.addCancelActionWithTitle(L10n.Localizable.Global.cancel) { controller.dismiss(animated: true, completion: nil) } controller.present(alert, animated: true, completion: nil) diff --git a/PIA VPN/String+VPNType.swift b/PIA VPN/String+VPNType.swift index f496752b1..4686e9d32 100644 --- a/PIA VPN/String+VPNType.swift +++ b/PIA VPN/String+VPNType.swift @@ -21,7 +21,8 @@ import Foundation import PIALibrary -import TunnelKit +import TunnelKitCore +import TunnelKitOpenVPN import PIAWireguard public extension String { @@ -46,12 +47,12 @@ public extension String { case PIATunnelProfile.vpnType: if AppPreferences.shared.piaSocketType != nil { let preferences = Client.preferences.editable() - if let currentOpenVPNConfiguration = preferences.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNTunnelProvider.Configuration { + if let currentOpenVPNConfiguration = preferences.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNProvider.Configuration { let port = currentOpenVPNConfiguration.sessionConfiguration.builder().endpointProtocols?.first?.port ?? 0 return "\(port)" } } else { - return L10n.Global.automatic + return L10n.Localizable.Global.automatic } return "---" case IKEv2Profile.vpnType: @@ -66,7 +67,7 @@ public extension String { case PIAWGTunnelProfile.vpnType, IKEv2Profile.vpnType: return "UDP" case PIATunnelProfile.vpnType: - return AppPreferences.shared.piaSocketType?.rawValue ?? L10n.Global.automatic + return AppPreferences.shared.piaSocketType?.rawValue ?? L10n.Localizable.Global.automatic default: return self @@ -93,7 +94,7 @@ public extension String { return "ChaCha20" case PIATunnelProfile.vpnType: let preferences = Client.preferences.editable() - if let currentOpenVPNConfiguration = preferences.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNTunnelProvider.Configuration { + if let currentOpenVPNConfiguration = preferences.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNProvider.Configuration { return currentOpenVPNConfiguration.sessionConfiguration.builder().cipher?.rawValue ?? "" } return "---" @@ -111,7 +112,7 @@ public extension String { return "Poly1305" case PIATunnelProfile.vpnType: let preferences = Client.preferences.editable() - if let currentOpenVPNConfiguration = preferences.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNTunnelProvider.Configuration { + if let currentOpenVPNConfiguration = preferences.vpnCustomConfiguration(for: PIATunnelProfile.vpnType) as? OpenVPNProvider.Configuration { return currentOpenVPNConfiguration.sessionConfiguration.builder().digest?.rawValue ?? "" } return "---" diff --git a/PIA VPN/SwiftGen+Assets.swift b/PIA VPN/SwiftGen+Assets.swift index 30dea8617..ad824e853 100644 --- a/PIA VPN/SwiftGen+Assets.swift +++ b/PIA VPN/SwiftGen+Assets.swift @@ -44,795 +44,870 @@ struct ColorAsset { // swiftlint:disable identifier_name line_length nesting type_body_length type_name enum Asset { - enum Cards { - enum WireGuard { - static let wgBackgroundDark = ImageAsset(name: "wg-background-dark") - static let wgBackgroundLight = ImageAsset(name: "wg-background-light") - static let wgMain = ImageAsset(name: "wg-main") - } - } - enum Piax { - enum DarkMap { - static let darkMap = ImageAsset(name: "Dark-Map") - } - enum Dashboard { - static let vpnButton = ImageAsset(name: "vpn-button") - } - enum Global { - static let browserDarkInactive = ImageAsset(name: "browser-dark-inactive") - static let browserLightInactive = ImageAsset(name: "browser-light-inactive") - static let dragDropIndicatorDark = ImageAsset(name: "drag-drop-indicator-dark") - static let dragDropIndicatorLight = ImageAsset(name: "drag-drop-indicator-light") - static let eyeActiveDark = ImageAsset(name: "eye-active-dark") - static let eyeActiveLight = ImageAsset(name: "eye-active-light") - static let eyeInactiveDark = ImageAsset(name: "eye-inactive-dark") - static let eyeInactiveLight = ImageAsset(name: "eye-inactive-light") - static let favoriteGreen = ImageAsset(name: "favorite-green") - static let favoriteSelected = ImageAsset(name: "favorite-selected") - static let favoriteUnselectedDark = ImageAsset(name: "favorite-unselected-dark") - static let favoriteUnselected = ImageAsset(name: "favorite-unselected") - static let iconBack = ImageAsset(name: "icon-back") - static let iconEditTile = ImageAsset(name: "icon-edit-tile") - static let iconFilter = ImageAsset(name: "icon-filter") - static let killswitchDarkActive = ImageAsset(name: "killswitch-dark-active") - static let killswitchDarkInactive = ImageAsset(name: "killswitch-dark-inactive") - static let killswitchLightInactive = ImageAsset(name: "killswitch-light-inactive") - static let nmtDarkActive = ImageAsset(name: "nmt-dark-active") - static let nmtDarkInactive = ImageAsset(name: "nmt-dark-inactive") - static let nmtLightActive = ImageAsset(name: "nmt-light-active") - static let nmtLightInactive = ImageAsset(name: "nmt-light-inactive") - static let regionSelected = ImageAsset(name: "region-selected") - static let themeDarkActive = ImageAsset(name: "theme-dark-active") - static let themeDarkInactive = ImageAsset(name: "theme-dark-inactive") - static let themeLightActive = ImageAsset(name: "theme-light-active") - static let themeLightInactive = ImageAsset(name: "theme-light-inactive") - static let trustedDarkIcon = ImageAsset(name: "trusted-dark-icon") - static let trustedLightIcon = ImageAsset(name: "trusted-light-icon") - static let untrustedDarkIcon = ImageAsset(name: "untrusted-dark-icon") - static let untrustedLightIcon = ImageAsset(name: "untrusted-light-icon") - } - enum Nmt { - static let iconAddRule = ImageAsset(name: "icon-add-rule") - static let iconCustomWifiConnect = ImageAsset(name: "icon-custom-wifi-connect") - static let iconCustomWifiDisconnect = ImageAsset(name: "icon-custom-wifi-disconnect") - static let iconCustomWifiRetain = ImageAsset(name: "icon-custom-wifi-retain") - static let iconDisconnect = ImageAsset(name: "icon-disconnect") - static let iconMobileDataConnect = ImageAsset(name: "icon-mobile-data-connect") - static let iconMobileDataDisconnect = ImageAsset(name: "icon-mobile-data-disconnect") - static let iconMobileDataRetain = ImageAsset(name: "icon-mobile-data-retain") - static let iconNmtConnect = ImageAsset(name: "icon-nmt-connect") - static let iconNmtWifi = ImageAsset(name: "icon-nmt-wifi") - static let iconOpenWifiConnect = ImageAsset(name: "icon-open-wifi-connect") - static let iconOpenWifiDisconnect = ImageAsset(name: "icon-open-wifi-disconnect") - static let iconOpenWifiRetain = ImageAsset(name: "icon-open-wifi-retain") - static let iconOptions = ImageAsset(name: "icon-options") - static let iconRetain = ImageAsset(name: "icon-retain") - static let iconSecureWifiConnect = ImageAsset(name: "icon-secure-wifi-connect") - static let iconSecureWifiDisconnect = ImageAsset(name: "icon-secure-wifi-disconnect") - static let iconSecureWifiRetain = ImageAsset(name: "icon-secure-wifi-retain") - static let iconSelect = ImageAsset(name: "icon-select") - } - enum Regions { - static let noResultsDark = ImageAsset(name: "no-results-dark") - static let noResultsLight = ImageAsset(name: "no-results-light") + enum Images { + enum Cards { + enum WireGuard { + static let wgBackgroundDark = ImageAsset(name: "wg-background-dark") + static let wgBackgroundLight = ImageAsset(name: "wg-background-light") + static let wgMain = ImageAsset(name: "wg-main") + } } - enum Settings { - static let iconAbout = ImageAsset(name: "icon-about") - static let iconAutomation = ImageAsset(name: "icon-automation") - static let iconGeneral = ImageAsset(name: "icon-general") - static let iconNetwork = ImageAsset(name: "icon-network") - static let iconPrivacy = ImageAsset(name: "icon-privacy") - static let iconProtocols = ImageAsset(name: "icon-protocols") + enum Piax { + enum DarkMap { + static let darkMap = ImageAsset(name: "Dark-Map") + } + enum Dashboard { + static let vpnButton = ImageAsset(name: "vpn-button") + } + enum Global { + static let browserDarkInactive = ImageAsset(name: "browser-dark-inactive") + static let browserLightInactive = ImageAsset(name: "browser-light-inactive") + static let dragDropIndicatorDark = ImageAsset(name: "drag-drop-indicator-dark") + static let dragDropIndicatorLight = ImageAsset(name: "drag-drop-indicator-light") + static let eyeActiveDark = ImageAsset(name: "eye-active-dark") + static let eyeActiveLight = ImageAsset(name: "eye-active-light") + static let eyeInactiveDark = ImageAsset(name: "eye-inactive-dark") + static let eyeInactiveLight = ImageAsset(name: "eye-inactive-light") + static let favoriteGreen = ImageAsset(name: "favorite-green") + static let favoriteSelected = ImageAsset(name: "favorite-selected") + static let favoriteUnselectedDark = ImageAsset(name: "favorite-unselected-dark") + static let favoriteUnselected = ImageAsset(name: "favorite-unselected") + static let iconBack = ImageAsset(name: "icon-back") + static let iconEditTile = ImageAsset(name: "icon-edit-tile") + static let iconFilter = ImageAsset(name: "icon-filter") + static let killswitchDarkActive = ImageAsset(name: "killswitch-dark-active") + static let killswitchDarkInactive = ImageAsset(name: "killswitch-dark-inactive") + static let killswitchLightInactive = ImageAsset(name: "killswitch-light-inactive") + static let nmtDarkActive = ImageAsset(name: "nmt-dark-active") + static let nmtDarkInactive = ImageAsset(name: "nmt-dark-inactive") + static let nmtLightActive = ImageAsset(name: "nmt-light-active") + static let nmtLightInactive = ImageAsset(name: "nmt-light-inactive") + static let regionSelected = ImageAsset(name: "region-selected") + static let themeDarkActive = ImageAsset(name: "theme-dark-active") + static let themeDarkInactive = ImageAsset(name: "theme-dark-inactive") + static let themeLightActive = ImageAsset(name: "theme-light-active") + static let themeLightInactive = ImageAsset(name: "theme-light-inactive") + static let trustedDarkIcon = ImageAsset(name: "trusted-dark-icon") + static let trustedLightIcon = ImageAsset(name: "trusted-light-icon") + static let untrustedDarkIcon = ImageAsset(name: "untrusted-dark-icon") + static let untrustedLightIcon = ImageAsset(name: "untrusted-light-icon") + } + enum Nmt { + static let iconAddRule = ImageAsset(name: "icon-add-rule") + static let iconCustomWifiConnect = ImageAsset(name: "icon-custom-wifi-connect") + static let iconCustomWifiDisconnect = ImageAsset(name: "icon-custom-wifi-disconnect") + static let iconCustomWifiRetain = ImageAsset(name: "icon-custom-wifi-retain") + static let iconDisconnect = ImageAsset(name: "icon-disconnect") + static let iconMobileDataConnect = ImageAsset(name: "icon-mobile-data-connect") + static let iconMobileDataDisconnect = ImageAsset(name: "icon-mobile-data-disconnect") + static let iconMobileDataRetain = ImageAsset(name: "icon-mobile-data-retain") + static let iconNmtConnect = ImageAsset(name: "icon-nmt-connect") + static let iconNmtWifi = ImageAsset(name: "icon-nmt-wifi") + static let iconOpenWifiConnect = ImageAsset(name: "icon-open-wifi-connect") + static let iconOpenWifiDisconnect = ImageAsset(name: "icon-open-wifi-disconnect") + static let iconOpenWifiRetain = ImageAsset(name: "icon-open-wifi-retain") + static let iconOptions = ImageAsset(name: "icon-options") + static let iconRetain = ImageAsset(name: "icon-retain") + static let iconSecureWifiConnect = ImageAsset(name: "icon-secure-wifi-connect") + static let iconSecureWifiDisconnect = ImageAsset(name: "icon-secure-wifi-disconnect") + static let iconSecureWifiRetain = ImageAsset(name: "icon-secure-wifi-retain") + static let iconSelect = ImageAsset(name: "icon-select") + } + enum Regions { + static let noResultsDark = ImageAsset(name: "no-results-dark") + static let noResultsLight = ImageAsset(name: "no-results-light") + } + enum Settings { + static let iconAbout = ImageAsset(name: "icon-about") + static let iconAutomation = ImageAsset(name: "icon-automation") + static let iconGeneral = ImageAsset(name: "icon-general") + static let iconNetwork = ImageAsset(name: "icon-network") + static let iconPrivacy = ImageAsset(name: "icon-privacy") + static let iconProtocols = ImageAsset(name: "icon-protocols") + } + enum Splash { + static let splash = ImageAsset(name: "splash") + } + enum Tiles { + enum ConnectionTile { + static let iconAuthentication = ImageAsset(name: "icon-authentication") + static let iconEncryption = ImageAsset(name: "icon-encryption") + static let iconHandshake = ImageAsset(name: "icon-handshake") + static let iconPort = ImageAsset(name: "icon-port") + static let iconProtocol = ImageAsset(name: "icon-protocol") + static let iconSocket = ImageAsset(name: "icon-socket") + } + static let ipTriangle = ImageAsset(name: "ip-triangle") + static let openTileDetails = ImageAsset(name: "open-tile-details") + static let quickConnectPlaceholderDark = ImageAsset(name: "quick-connect-placeholder-dark") + static let quickConnectPlaceholderLight = ImageAsset(name: "quick-connect-placeholder-light") + } } - enum Splash { - static let splash = ImageAsset(name: "splash") + static let accessoryExpire = ImageAsset(name: "accessory-expire") + static let accessorySelected = ImageAsset(name: "accessory-selected") + static let buttonDown = ImageAsset(name: "button-down") + static let buttonUp = ImageAsset(name: "button-up") + static let copyIcon = ImageAsset(name: "copy-icon") + static let dipBadgeDark = ImageAsset(name: "dip-badge-dark") + static let dipBadgeLight = ImageAsset(name: "dip-badge-light") + enum Flags { + static let flagAd = ImageAsset(name: "flag-ad") + static let flagAe = ImageAsset(name: "flag-ae") + static let flagAf = ImageAsset(name: "flag-af") + static let flagAg = ImageAsset(name: "flag-ag") + static let flagAi = ImageAsset(name: "flag-ai") + static let flagAl = ImageAsset(name: "flag-al") + static let flagAm = ImageAsset(name: "flag-am") + static let flagAo = ImageAsset(name: "flag-ao") + static let flagAq = ImageAsset(name: "flag-aq") + static let flagAr = ImageAsset(name: "flag-ar") + static let flagAs = ImageAsset(name: "flag-as") + static let flagAt = ImageAsset(name: "flag-at") + static let flagAu = ImageAsset(name: "flag-au") + static let flagAw = ImageAsset(name: "flag-aw") + static let flagAx = ImageAsset(name: "flag-ax") + static let flagAz = ImageAsset(name: "flag-az") + static let flagBa = ImageAsset(name: "flag-ba") + static let flagBb = ImageAsset(name: "flag-bb") + static let flagBd = ImageAsset(name: "flag-bd") + static let flagBe = ImageAsset(name: "flag-be") + static let flagBf = ImageAsset(name: "flag-bf") + static let flagBg = ImageAsset(name: "flag-bg") + static let flagBh = ImageAsset(name: "flag-bh") + static let flagBi = ImageAsset(name: "flag-bi") + static let flagBj = ImageAsset(name: "flag-bj") + static let flagBl = ImageAsset(name: "flag-bl") + static let flagBm = ImageAsset(name: "flag-bm") + static let flagBn = ImageAsset(name: "flag-bn") + static let flagBo = ImageAsset(name: "flag-bo") + static let flagBq = ImageAsset(name: "flag-bq") + static let flagBr = ImageAsset(name: "flag-br") + static let flagBs = ImageAsset(name: "flag-bs") + static let flagBt = ImageAsset(name: "flag-bt") + static let flagBv = ImageAsset(name: "flag-bv") + static let flagBw = ImageAsset(name: "flag-bw") + static let flagBy = ImageAsset(name: "flag-by") + static let flagBz = ImageAsset(name: "flag-bz") + static let flagCa = ImageAsset(name: "flag-ca") + static let flagCc = ImageAsset(name: "flag-cc") + static let flagCd = ImageAsset(name: "flag-cd") + static let flagCf = ImageAsset(name: "flag-cf") + static let flagCg = ImageAsset(name: "flag-cg") + static let flagCh = ImageAsset(name: "flag-ch") + static let flagCi = ImageAsset(name: "flag-ci") + static let flagCk = ImageAsset(name: "flag-ck") + static let flagCl = ImageAsset(name: "flag-cl") + static let flagCm = ImageAsset(name: "flag-cm") + static let flagCn = ImageAsset(name: "flag-cn") + static let flagCo = ImageAsset(name: "flag-co") + static let flagCr = ImageAsset(name: "flag-cr") + static let flagCu = ImageAsset(name: "flag-cu") + static let flagCv = ImageAsset(name: "flag-cv") + static let flagCw = ImageAsset(name: "flag-cw") + static let flagCx = ImageAsset(name: "flag-cx") + static let flagCy = ImageAsset(name: "flag-cy") + static let flagCz = ImageAsset(name: "flag-cz") + static let flagDe = ImageAsset(name: "flag-de") + static let flagDj = ImageAsset(name: "flag-dj") + static let flagDk = ImageAsset(name: "flag-dk") + static let flagDm = ImageAsset(name: "flag-dm") + static let flagDo = ImageAsset(name: "flag-do") + static let flagDz = ImageAsset(name: "flag-dz") + static let flagEc = ImageAsset(name: "flag-ec") + static let flagEe = ImageAsset(name: "flag-ee") + static let flagEg = ImageAsset(name: "flag-eg") + static let flagEh = ImageAsset(name: "flag-eh") + static let flagEr = ImageAsset(name: "flag-er") + static let flagEsCt = ImageAsset(name: "flag-es-ct") + static let flagEs = ImageAsset(name: "flag-es") + static let flagEt = ImageAsset(name: "flag-et") + static let flagEu = ImageAsset(name: "flag-eu") + static let flagFi = ImageAsset(name: "flag-fi") + static let flagFj = ImageAsset(name: "flag-fj") + static let flagFk = ImageAsset(name: "flag-fk") + static let flagFm = ImageAsset(name: "flag-fm") + static let flagFo = ImageAsset(name: "flag-fo") + static let flagFr = ImageAsset(name: "flag-fr") + static let flagGa = ImageAsset(name: "flag-ga") + static let flagGbEng = ImageAsset(name: "flag-gb-eng") + static let flagGbNir = ImageAsset(name: "flag-gb-nir") + static let flagGbSct = ImageAsset(name: "flag-gb-sct") + static let flagGbWls = ImageAsset(name: "flag-gb-wls") + static let flagGb = ImageAsset(name: "flag-gb") + static let flagGd = ImageAsset(name: "flag-gd") + static let flagGe = ImageAsset(name: "flag-ge") + static let flagGf = ImageAsset(name: "flag-gf") + static let flagGg = ImageAsset(name: "flag-gg") + static let flagGh = ImageAsset(name: "flag-gh") + static let flagGi = ImageAsset(name: "flag-gi") + static let flagGl = ImageAsset(name: "flag-gl") + static let flagGm = ImageAsset(name: "flag-gm") + static let flagGn = ImageAsset(name: "flag-gn") + static let flagGp = ImageAsset(name: "flag-gp") + static let flagGq = ImageAsset(name: "flag-gq") + static let flagGr = ImageAsset(name: "flag-gr") + static let flagGs = ImageAsset(name: "flag-gs") + static let flagGt = ImageAsset(name: "flag-gt") + static let flagGu = ImageAsset(name: "flag-gu") + static let flagGw = ImageAsset(name: "flag-gw") + static let flagGy = ImageAsset(name: "flag-gy") + static let flagHk = ImageAsset(name: "flag-hk") + static let flagHm = ImageAsset(name: "flag-hm") + static let flagHn = ImageAsset(name: "flag-hn") + static let flagHr = ImageAsset(name: "flag-hr") + static let flagHt = ImageAsset(name: "flag-ht") + static let flagHu = ImageAsset(name: "flag-hu") + static let flagId = ImageAsset(name: "flag-id") + static let flagIe = ImageAsset(name: "flag-ie") + static let flagIl = ImageAsset(name: "flag-il") + static let flagIm = ImageAsset(name: "flag-im") + static let flagIn = ImageAsset(name: "flag-in") + static let flagIo = ImageAsset(name: "flag-io") + static let flagIq = ImageAsset(name: "flag-iq") + static let flagIr = ImageAsset(name: "flag-ir") + static let flagIs = ImageAsset(name: "flag-is") + static let flagIt = ImageAsset(name: "flag-it") + static let flagJe = ImageAsset(name: "flag-je") + static let flagJm = ImageAsset(name: "flag-jm") + static let flagJo = ImageAsset(name: "flag-jo") + static let flagJp = ImageAsset(name: "flag-jp") + static let flagKe = ImageAsset(name: "flag-ke") + static let flagKg = ImageAsset(name: "flag-kg") + static let flagKh = ImageAsset(name: "flag-kh") + static let flagKi = ImageAsset(name: "flag-ki") + static let flagKm = ImageAsset(name: "flag-km") + static let flagKn = ImageAsset(name: "flag-kn") + static let flagKp = ImageAsset(name: "flag-kp") + static let flagKr = ImageAsset(name: "flag-kr") + static let flagKw = ImageAsset(name: "flag-kw") + static let flagKy = ImageAsset(name: "flag-ky") + static let flagKz = ImageAsset(name: "flag-kz") + static let flagLa = ImageAsset(name: "flag-la") + static let flagLb = ImageAsset(name: "flag-lb") + static let flagLc = ImageAsset(name: "flag-lc") + static let flagLi = ImageAsset(name: "flag-li") + static let flagLk = ImageAsset(name: "flag-lk") + static let flagLr = ImageAsset(name: "flag-lr") + static let flagLs = ImageAsset(name: "flag-ls") + static let flagLt = ImageAsset(name: "flag-lt") + static let flagLu = ImageAsset(name: "flag-lu") + static let flagLv = ImageAsset(name: "flag-lv") + static let flagLy = ImageAsset(name: "flag-ly") + static let flagMa = ImageAsset(name: "flag-ma") + static let flagMc = ImageAsset(name: "flag-mc") + static let flagMd = ImageAsset(name: "flag-md") + static let flagMe = ImageAsset(name: "flag-me") + static let flagMf = ImageAsset(name: "flag-mf") + static let flagMg = ImageAsset(name: "flag-mg") + static let flagMh = ImageAsset(name: "flag-mh") + static let flagMk = ImageAsset(name: "flag-mk") + static let flagMl = ImageAsset(name: "flag-ml") + static let flagMm = ImageAsset(name: "flag-mm") + static let flagMn = ImageAsset(name: "flag-mn") + static let flagMo = ImageAsset(name: "flag-mo") + static let flagMp = ImageAsset(name: "flag-mp") + static let flagMq = ImageAsset(name: "flag-mq") + static let flagMr = ImageAsset(name: "flag-mr") + static let flagMs = ImageAsset(name: "flag-ms") + static let flagMt = ImageAsset(name: "flag-mt") + static let flagMu = ImageAsset(name: "flag-mu") + static let flagMv = ImageAsset(name: "flag-mv") + static let flagMw = ImageAsset(name: "flag-mw") + static let flagMx = ImageAsset(name: "flag-mx") + static let flagMy = ImageAsset(name: "flag-my") + static let flagMz = ImageAsset(name: "flag-mz") + static let flagNa = ImageAsset(name: "flag-na") + static let flagNc = ImageAsset(name: "flag-nc") + static let flagNe = ImageAsset(name: "flag-ne") + static let flagNf = ImageAsset(name: "flag-nf") + static let flagNg = ImageAsset(name: "flag-ng") + static let flagNi = ImageAsset(name: "flag-ni") + static let flagNl = ImageAsset(name: "flag-nl") + static let flagNo = ImageAsset(name: "flag-no") + static let flagNp = ImageAsset(name: "flag-np") + static let flagNr = ImageAsset(name: "flag-nr") + static let flagNu = ImageAsset(name: "flag-nu") + static let flagNz = ImageAsset(name: "flag-nz") + static let flagOm = ImageAsset(name: "flag-om") + static let flagPa = ImageAsset(name: "flag-pa") + static let flagPe = ImageAsset(name: "flag-pe") + static let flagPf = ImageAsset(name: "flag-pf") + static let flagPg = ImageAsset(name: "flag-pg") + static let flagPh = ImageAsset(name: "flag-ph") + static let flagPk = ImageAsset(name: "flag-pk") + static let flagPl = ImageAsset(name: "flag-pl") + static let flagPm = ImageAsset(name: "flag-pm") + static let flagPn = ImageAsset(name: "flag-pn") + static let flagPr = ImageAsset(name: "flag-pr") + static let flagPs = ImageAsset(name: "flag-ps") + static let flagPt = ImageAsset(name: "flag-pt") + static let flagPw = ImageAsset(name: "flag-pw") + static let flagPy = ImageAsset(name: "flag-py") + static let flagQa = ImageAsset(name: "flag-qa") + static let flagRe = ImageAsset(name: "flag-re") + static let flagRo = ImageAsset(name: "flag-ro") + static let flagRs = ImageAsset(name: "flag-rs") + static let flagRu = ImageAsset(name: "flag-ru") + static let flagRw = ImageAsset(name: "flag-rw") + static let flagSa = ImageAsset(name: "flag-sa") + static let flagSb = ImageAsset(name: "flag-sb") + static let flagSc = ImageAsset(name: "flag-sc") + static let flagSd = ImageAsset(name: "flag-sd") + static let flagSe = ImageAsset(name: "flag-se") + static let flagSg = ImageAsset(name: "flag-sg") + static let flagSh = ImageAsset(name: "flag-sh") + static let flagSi = ImageAsset(name: "flag-si") + static let flagSj = ImageAsset(name: "flag-sj") + static let flagSk = ImageAsset(name: "flag-sk") + static let flagSl = ImageAsset(name: "flag-sl") + static let flagSm = ImageAsset(name: "flag-sm") + static let flagSn = ImageAsset(name: "flag-sn") + static let flagSo = ImageAsset(name: "flag-so") + static let flagSr = ImageAsset(name: "flag-sr") + static let flagSs = ImageAsset(name: "flag-ss") + static let flagSt = ImageAsset(name: "flag-st") + static let flagSv = ImageAsset(name: "flag-sv") + static let flagSx = ImageAsset(name: "flag-sx") + static let flagSy = ImageAsset(name: "flag-sy") + static let flagSz = ImageAsset(name: "flag-sz") + static let flagTc = ImageAsset(name: "flag-tc") + static let flagTd = ImageAsset(name: "flag-td") + static let flagTf = ImageAsset(name: "flag-tf") + static let flagTg = ImageAsset(name: "flag-tg") + static let flagTh = ImageAsset(name: "flag-th") + static let flagTj = ImageAsset(name: "flag-tj") + static let flagTk = ImageAsset(name: "flag-tk") + static let flagTl = ImageAsset(name: "flag-tl") + static let flagTm = ImageAsset(name: "flag-tm") + static let flagTn = ImageAsset(name: "flag-tn") + static let flagTo = ImageAsset(name: "flag-to") + static let flagTr = ImageAsset(name: "flag-tr") + static let flagTt = ImageAsset(name: "flag-tt") + static let flagTv = ImageAsset(name: "flag-tv") + static let flagTw = ImageAsset(name: "flag-tw") + static let flagTz = ImageAsset(name: "flag-tz") + static let flagUa = ImageAsset(name: "flag-ua") + static let flagUg = ImageAsset(name: "flag-ug") + static let flagUm = ImageAsset(name: "flag-um") + static let flagUn = ImageAsset(name: "flag-un") + static let flagUniversal = ImageAsset(name: "flag-universal") + static let flagUs = ImageAsset(name: "flag-us") + static let flagUy = ImageAsset(name: "flag-uy") + static let flagUz = ImageAsset(name: "flag-uz") + static let flagVa = ImageAsset(name: "flag-va") + static let flagVc = ImageAsset(name: "flag-vc") + static let flagVe = ImageAsset(name: "flag-ve") + static let flagVg = ImageAsset(name: "flag-vg") + static let flagVi = ImageAsset(name: "flag-vi") + static let flagVn = ImageAsset(name: "flag-vn") + static let flagVu = ImageAsset(name: "flag-vu") + static let flagWf = ImageAsset(name: "flag-wf") + static let flagWs = ImageAsset(name: "flag-ws") + static let flagYe = ImageAsset(name: "flag-ye") + static let flagYt = ImageAsset(name: "flag-yt") + static let flagZa = ImageAsset(name: "flag-za") + static let flagZm = ImageAsset(name: "flag-zm") + static let flagZw = ImageAsset(name: "flag-zw") } - enum Tiles { - enum ConnectionTile { - static let iconAuthentication = ImageAsset(name: "icon-authentication") - static let iconEncryption = ImageAsset(name: "icon-encryption") - static let iconHandshake = ImageAsset(name: "icon-handshake") - static let iconPort = ImageAsset(name: "icon-port") - static let iconProtocol = ImageAsset(name: "icon-protocol") - static let iconSocket = ImageAsset(name: "icon-socket") + static let icon3dtConnect = ImageAsset(name: "icon-3dt-connect") + static let icon3dtDisconnect = ImageAsset(name: "icon-3dt-disconnect") + static let icon3dtSelectRegion = ImageAsset(name: "icon-3dt-select-region") + static let iconAbout1 = ImageAsset(name: "icon-about-1") + static let iconAccount = ImageAsset(name: "icon-account") + static let iconAdd = ImageAsset(name: "icon-add") + static let iconAlert = ImageAsset(name: "icon-alert") + static let iconAutomation = ImageAsset(name: "icon-automation") + static let iconClose = ImageAsset(name: "icon-close") + static let iconContact = ImageAsset(name: "icon-contact") + static let iconDip = ImageAsset(name: "icon-dip") + static let iconGeneral = ImageAsset(name: "icon-general") + static let iconGeoDarkSelected = ImageAsset(name: "icon-geo-dark-selected") + static let iconGeoDark = ImageAsset(name: "icon-geo-dark") + static let iconGeoSelected = ImageAsset(name: "icon-geo-selected") + static let iconGeo = ImageAsset(name: "icon-geo") + static let iconHomepage = ImageAsset(name: "icon-homepage") + static let iconLogout = ImageAsset(name: "icon-logout") + static let iconNetwork = ImageAsset(name: "icon-network") + static let iconPrivacy1 = ImageAsset(name: "icon-privacy-1") + static let iconProtocols = ImageAsset(name: "icon-protocols") + static let iconRegion = ImageAsset(name: "icon-region") + static let iconRemove = ImageAsset(name: "icon-remove") + static let iconSettings = ImageAsset(name: "icon-settings") + static let iconTrashDark = ImageAsset(name: "icon-trash-dark") + static let iconTrash = ImageAsset(name: "icon-trash") + static let iconWarning = ImageAsset(name: "icon-warning") + static let iconWifi = ImageAsset(name: "icon-wifi") + static let iconmenuAbout = ImageAsset(name: "iconmenu-about") + static let iconmenuPrivacy = ImageAsset(name: "iconmenu-privacy") + static let imageContentBlocker = ImageAsset(name: "image-content-blocker") + static let imagePurchaseSuccess = ImageAsset(name: "image-purchase-success") + static let imageRobot = ImageAsset(name: "image-robot") + static let imageVpnAllow = ImageAsset(name: "image-vpn-allow") + static let itemMenu = ImageAsset(name: "item-menu") + static let navLogoWhite = ImageAsset(name: "nav-logo-white") + static let navLogo = ImageAsset(name: "nav-logo") + static let offlineServerIcon = ImageAsset(name: "offline-server-icon") + static let shareIcon = ImageAsset(name: "share-icon") + + // swiftlint:disable trailing_comma + static let allColors: [ColorAsset] = [ + ] + static let allImages: [ImageAsset] = [ + Cards.WireGuard.wgBackgroundDark, + Cards.WireGuard.wgBackgroundLight, + Cards.WireGuard.wgMain, + Piax.DarkMap.darkMap, + Piax.Dashboard.vpnButton, + Piax.Global.browserDarkInactive, + Piax.Global.browserLightInactive, + Piax.Global.dragDropIndicatorDark, + Piax.Global.dragDropIndicatorLight, + Piax.Global.eyeActiveDark, + Piax.Global.eyeActiveLight, + Piax.Global.eyeInactiveDark, + Piax.Global.eyeInactiveLight, + Piax.Global.favoriteGreen, + Piax.Global.favoriteSelected, + Piax.Global.favoriteUnselectedDark, + Piax.Global.favoriteUnselected, + Piax.Global.iconBack, + Piax.Global.iconEditTile, + Piax.Global.iconFilter, + Piax.Global.killswitchDarkActive, + Piax.Global.killswitchDarkInactive, + Piax.Global.killswitchLightInactive, + Piax.Global.nmtDarkActive, + Piax.Global.nmtDarkInactive, + Piax.Global.nmtLightActive, + Piax.Global.nmtLightInactive, + Piax.Global.regionSelected, + Piax.Global.themeDarkActive, + Piax.Global.themeDarkInactive, + Piax.Global.themeLightActive, + Piax.Global.themeLightInactive, + Piax.Global.trustedDarkIcon, + Piax.Global.trustedLightIcon, + Piax.Global.untrustedDarkIcon, + Piax.Global.untrustedLightIcon, + Piax.Nmt.iconAddRule, + Piax.Nmt.iconCustomWifiConnect, + Piax.Nmt.iconCustomWifiDisconnect, + Piax.Nmt.iconCustomWifiRetain, + Piax.Nmt.iconDisconnect, + Piax.Nmt.iconMobileDataConnect, + Piax.Nmt.iconMobileDataDisconnect, + Piax.Nmt.iconMobileDataRetain, + Piax.Nmt.iconNmtConnect, + Piax.Nmt.iconNmtWifi, + Piax.Nmt.iconOpenWifiConnect, + Piax.Nmt.iconOpenWifiDisconnect, + Piax.Nmt.iconOpenWifiRetain, + Piax.Nmt.iconOptions, + Piax.Nmt.iconRetain, + Piax.Nmt.iconSecureWifiConnect, + Piax.Nmt.iconSecureWifiDisconnect, + Piax.Nmt.iconSecureWifiRetain, + Piax.Nmt.iconSelect, + Piax.Regions.noResultsDark, + Piax.Regions.noResultsLight, + Piax.Settings.iconAbout, + Piax.Settings.iconAutomation, + Piax.Settings.iconGeneral, + Piax.Settings.iconNetwork, + Piax.Settings.iconPrivacy, + Piax.Settings.iconProtocols, + Piax.Splash.splash, + Piax.Tiles.ConnectionTile.iconAuthentication, + Piax.Tiles.ConnectionTile.iconEncryption, + Piax.Tiles.ConnectionTile.iconHandshake, + Piax.Tiles.ConnectionTile.iconPort, + Piax.Tiles.ConnectionTile.iconProtocol, + Piax.Tiles.ConnectionTile.iconSocket, + Piax.Tiles.ipTriangle, + Piax.Tiles.openTileDetails, + Piax.Tiles.quickConnectPlaceholderDark, + Piax.Tiles.quickConnectPlaceholderLight, + accessoryExpire, + accessorySelected, + buttonDown, + buttonUp, + copyIcon, + dipBadgeDark, + dipBadgeLight, + Flags.flagAd, + Flags.flagAe, + Flags.flagAf, + Flags.flagAg, + Flags.flagAi, + Flags.flagAl, + Flags.flagAm, + Flags.flagAo, + Flags.flagAq, + Flags.flagAr, + Flags.flagAs, + Flags.flagAt, + Flags.flagAu, + Flags.flagAw, + Flags.flagAx, + Flags.flagAz, + Flags.flagBa, + Flags.flagBb, + Flags.flagBd, + Flags.flagBe, + Flags.flagBf, + Flags.flagBg, + Flags.flagBh, + Flags.flagBi, + Flags.flagBj, + Flags.flagBl, + Flags.flagBm, + Flags.flagBn, + Flags.flagBo, + Flags.flagBq, + Flags.flagBr, + Flags.flagBs, + Flags.flagBt, + Flags.flagBv, + Flags.flagBw, + Flags.flagBy, + Flags.flagBz, + Flags.flagCa, + Flags.flagCc, + Flags.flagCd, + Flags.flagCf, + Flags.flagCg, + Flags.flagCh, + Flags.flagCi, + Flags.flagCk, + Flags.flagCl, + Flags.flagCm, + Flags.flagCn, + Flags.flagCo, + Flags.flagCr, + Flags.flagCu, + Flags.flagCv, + Flags.flagCw, + Flags.flagCx, + Flags.flagCy, + Flags.flagCz, + Flags.flagDe, + Flags.flagDj, + Flags.flagDk, + Flags.flagDm, + Flags.flagDo, + Flags.flagDz, + Flags.flagEc, + Flags.flagEe, + Flags.flagEg, + Flags.flagEh, + Flags.flagEr, + Flags.flagEsCt, + Flags.flagEs, + Flags.flagEt, + Flags.flagEu, + Flags.flagFi, + Flags.flagFj, + Flags.flagFk, + Flags.flagFm, + Flags.flagFo, + Flags.flagFr, + Flags.flagGa, + Flags.flagGbEng, + Flags.flagGbNir, + Flags.flagGbSct, + Flags.flagGbWls, + Flags.flagGb, + Flags.flagGd, + Flags.flagGe, + Flags.flagGf, + Flags.flagGg, + Flags.flagGh, + Flags.flagGi, + Flags.flagGl, + Flags.flagGm, + Flags.flagGn, + Flags.flagGp, + Flags.flagGq, + Flags.flagGr, + Flags.flagGs, + Flags.flagGt, + Flags.flagGu, + Flags.flagGw, + Flags.flagGy, + Flags.flagHk, + Flags.flagHm, + Flags.flagHn, + Flags.flagHr, + Flags.flagHt, + Flags.flagHu, + Flags.flagId, + Flags.flagIe, + Flags.flagIl, + Flags.flagIm, + Flags.flagIn, + Flags.flagIo, + Flags.flagIq, + Flags.flagIr, + Flags.flagIs, + Flags.flagIt, + Flags.flagJe, + Flags.flagJm, + Flags.flagJo, + Flags.flagJp, + Flags.flagKe, + Flags.flagKg, + Flags.flagKh, + Flags.flagKi, + Flags.flagKm, + Flags.flagKn, + Flags.flagKp, + Flags.flagKr, + Flags.flagKw, + Flags.flagKy, + Flags.flagKz, + Flags.flagLa, + Flags.flagLb, + Flags.flagLc, + Flags.flagLi, + Flags.flagLk, + Flags.flagLr, + Flags.flagLs, + Flags.flagLt, + Flags.flagLu, + Flags.flagLv, + Flags.flagLy, + Flags.flagMa, + Flags.flagMc, + Flags.flagMd, + Flags.flagMe, + Flags.flagMf, + Flags.flagMg, + Flags.flagMh, + Flags.flagMk, + Flags.flagMl, + Flags.flagMm, + Flags.flagMn, + Flags.flagMo, + Flags.flagMp, + Flags.flagMq, + Flags.flagMr, + Flags.flagMs, + Flags.flagMt, + Flags.flagMu, + Flags.flagMv, + Flags.flagMw, + Flags.flagMx, + Flags.flagMy, + Flags.flagMz, + Flags.flagNa, + Flags.flagNc, + Flags.flagNe, + Flags.flagNf, + Flags.flagNg, + Flags.flagNi, + Flags.flagNl, + Flags.flagNo, + Flags.flagNp, + Flags.flagNr, + Flags.flagNu, + Flags.flagNz, + Flags.flagOm, + Flags.flagPa, + Flags.flagPe, + Flags.flagPf, + Flags.flagPg, + Flags.flagPh, + Flags.flagPk, + Flags.flagPl, + Flags.flagPm, + Flags.flagPn, + Flags.flagPr, + Flags.flagPs, + Flags.flagPt, + Flags.flagPw, + Flags.flagPy, + Flags.flagQa, + Flags.flagRe, + Flags.flagRo, + Flags.flagRs, + Flags.flagRu, + Flags.flagRw, + Flags.flagSa, + Flags.flagSb, + Flags.flagSc, + Flags.flagSd, + Flags.flagSe, + Flags.flagSg, + Flags.flagSh, + Flags.flagSi, + Flags.flagSj, + Flags.flagSk, + Flags.flagSl, + Flags.flagSm, + Flags.flagSn, + Flags.flagSo, + Flags.flagSr, + Flags.flagSs, + Flags.flagSt, + Flags.flagSv, + Flags.flagSx, + Flags.flagSy, + Flags.flagSz, + Flags.flagTc, + Flags.flagTd, + Flags.flagTf, + Flags.flagTg, + Flags.flagTh, + Flags.flagTj, + Flags.flagTk, + Flags.flagTl, + Flags.flagTm, + Flags.flagTn, + Flags.flagTo, + Flags.flagTr, + Flags.flagTt, + Flags.flagTv, + Flags.flagTw, + Flags.flagTz, + Flags.flagUa, + Flags.flagUg, + Flags.flagUm, + Flags.flagUn, + Flags.flagUniversal, + Flags.flagUs, + Flags.flagUy, + Flags.flagUz, + Flags.flagVa, + Flags.flagVc, + Flags.flagVe, + Flags.flagVg, + Flags.flagVi, + Flags.flagVn, + Flags.flagVu, + Flags.flagWf, + Flags.flagWs, + Flags.flagYe, + Flags.flagYt, + Flags.flagZa, + Flags.flagZm, + Flags.flagZw, + icon3dtConnect, + icon3dtDisconnect, + icon3dtSelectRegion, + iconAbout1, + iconAccount, + iconAdd, + iconAlert, + iconAutomation, + iconClose, + iconContact, + iconDip, + iconGeneral, + iconGeoDarkSelected, + iconGeoDark, + iconGeoSelected, + iconGeo, + iconHomepage, + iconLogout, + iconNetwork, + iconPrivacy1, + iconProtocols, + iconRegion, + iconRemove, + iconSettings, + iconTrashDark, + iconTrash, + iconWarning, + iconWifi, + iconmenuAbout, + iconmenuPrivacy, + imageContentBlocker, + imagePurchaseSuccess, + imageRobot, + imageVpnAllow, + itemMenu, + navLogoWhite, + navLogo, + offlineServerIcon, + shareIcon, + ] + // swiftlint:enable trailing_comma + @available(*, deprecated, renamed: "allImages") + static let allValues: [AssetType] = allImages + } + enum Ui { + enum Piax { + enum Global { + static let centeredDarkMap = ImageAsset(name: "centered-dark-map") + static let centeredLightMap = ImageAsset(name: "centered-light-map") + static let computerIcon = ImageAsset(name: "computer-icon") + static let globeIcon = ImageAsset(name: "globe-icon") + static let iconBack = ImageAsset(name: "icon-back") + static let iconCamera = ImageAsset(name: "icon-camera") + static let iconClose = ImageAsset(name: "icon-close") + static let iconWarning = ImageAsset(name: "icon-warning") + static let pagecontrolSelectedDot = ImageAsset(name: "pagecontrol-selected-dot") + static let pagecontrolUnselectedDot = ImageAsset(name: "pagecontrol-unselected-dot") + static let planSelected = ImageAsset(name: "plan-selected") + static let planUnselected = ImageAsset(name: "plan-unselected") + static let scrollableMapDark = ImageAsset(name: "scrollableMap-dark") + static let scrollableMapLight = ImageAsset(name: "scrollableMap-light") + static let shieldIcon = ImageAsset(name: "shield-icon") } - static let ipTriangle = ImageAsset(name: "ip-triangle") - static let openTileDetails = ImageAsset(name: "open-tile-details") - static let quickConnectPlaceholderDark = ImageAsset(name: "quick-connect-placeholder-dark") - static let quickConnectPlaceholderLight = ImageAsset(name: "quick-connect-placeholder-light") } - } - static let accessoryExpire = ImageAsset(name: "accessory-expire") - static let accessorySelected = ImageAsset(name: "accessory-selected") - static let buttonDown = ImageAsset(name: "button-down") - static let buttonUp = ImageAsset(name: "button-up") - static let copyIcon = ImageAsset(name: "copy-icon") - static let dipBadgeDark = ImageAsset(name: "dip-badge-dark") - static let dipBadgeLight = ImageAsset(name: "dip-badge-light") - enum Flags { - static let flagAd = ImageAsset(name: "flag-ad") - static let flagAe = ImageAsset(name: "flag-ae") - static let flagAf = ImageAsset(name: "flag-af") - static let flagAg = ImageAsset(name: "flag-ag") - static let flagAi = ImageAsset(name: "flag-ai") - static let flagAl = ImageAsset(name: "flag-al") - static let flagAm = ImageAsset(name: "flag-am") - static let flagAo = ImageAsset(name: "flag-ao") - static let flagAq = ImageAsset(name: "flag-aq") - static let flagAr = ImageAsset(name: "flag-ar") - static let flagAs = ImageAsset(name: "flag-as") - static let flagAt = ImageAsset(name: "flag-at") - static let flagAu = ImageAsset(name: "flag-au") - static let flagAw = ImageAsset(name: "flag-aw") - static let flagAx = ImageAsset(name: "flag-ax") - static let flagAz = ImageAsset(name: "flag-az") - static let flagBa = ImageAsset(name: "flag-ba") - static let flagBb = ImageAsset(name: "flag-bb") - static let flagBd = ImageAsset(name: "flag-bd") - static let flagBe = ImageAsset(name: "flag-be") - static let flagBf = ImageAsset(name: "flag-bf") - static let flagBg = ImageAsset(name: "flag-bg") - static let flagBh = ImageAsset(name: "flag-bh") - static let flagBi = ImageAsset(name: "flag-bi") - static let flagBj = ImageAsset(name: "flag-bj") - static let flagBl = ImageAsset(name: "flag-bl") - static let flagBm = ImageAsset(name: "flag-bm") - static let flagBn = ImageAsset(name: "flag-bn") - static let flagBo = ImageAsset(name: "flag-bo") - static let flagBq = ImageAsset(name: "flag-bq") - static let flagBr = ImageAsset(name: "flag-br") - static let flagBs = ImageAsset(name: "flag-bs") - static let flagBt = ImageAsset(name: "flag-bt") - static let flagBv = ImageAsset(name: "flag-bv") - static let flagBw = ImageAsset(name: "flag-bw") - static let flagBy = ImageAsset(name: "flag-by") - static let flagBz = ImageAsset(name: "flag-bz") - static let flagCa = ImageAsset(name: "flag-ca") - static let flagCc = ImageAsset(name: "flag-cc") - static let flagCd = ImageAsset(name: "flag-cd") - static let flagCf = ImageAsset(name: "flag-cf") - static let flagCg = ImageAsset(name: "flag-cg") - static let flagCh = ImageAsset(name: "flag-ch") - static let flagCi = ImageAsset(name: "flag-ci") - static let flagCk = ImageAsset(name: "flag-ck") - static let flagCl = ImageAsset(name: "flag-cl") - static let flagCm = ImageAsset(name: "flag-cm") - static let flagCn = ImageAsset(name: "flag-cn") - static let flagCo = ImageAsset(name: "flag-co") - static let flagCr = ImageAsset(name: "flag-cr") - static let flagCu = ImageAsset(name: "flag-cu") - static let flagCv = ImageAsset(name: "flag-cv") - static let flagCw = ImageAsset(name: "flag-cw") - static let flagCx = ImageAsset(name: "flag-cx") - static let flagCy = ImageAsset(name: "flag-cy") - static let flagCz = ImageAsset(name: "flag-cz") - static let flagDe = ImageAsset(name: "flag-de") - static let flagDj = ImageAsset(name: "flag-dj") - static let flagDk = ImageAsset(name: "flag-dk") - static let flagDm = ImageAsset(name: "flag-dm") - static let flagDo = ImageAsset(name: "flag-do") - static let flagDz = ImageAsset(name: "flag-dz") - static let flagEc = ImageAsset(name: "flag-ec") - static let flagEe = ImageAsset(name: "flag-ee") - static let flagEg = ImageAsset(name: "flag-eg") - static let flagEh = ImageAsset(name: "flag-eh") - static let flagEr = ImageAsset(name: "flag-er") - static let flagEsCt = ImageAsset(name: "flag-es-ct") - static let flagEs = ImageAsset(name: "flag-es") - static let flagEt = ImageAsset(name: "flag-et") - static let flagEu = ImageAsset(name: "flag-eu") - static let flagFi = ImageAsset(name: "flag-fi") - static let flagFj = ImageAsset(name: "flag-fj") - static let flagFk = ImageAsset(name: "flag-fk") - static let flagFm = ImageAsset(name: "flag-fm") - static let flagFo = ImageAsset(name: "flag-fo") - static let flagFr = ImageAsset(name: "flag-fr") - static let flagGa = ImageAsset(name: "flag-ga") - static let flagGbEng = ImageAsset(name: "flag-gb-eng") - static let flagGbNir = ImageAsset(name: "flag-gb-nir") - static let flagGbSct = ImageAsset(name: "flag-gb-sct") - static let flagGbWls = ImageAsset(name: "flag-gb-wls") - static let flagGb = ImageAsset(name: "flag-gb") - static let flagGd = ImageAsset(name: "flag-gd") - static let flagGe = ImageAsset(name: "flag-ge") - static let flagGf = ImageAsset(name: "flag-gf") - static let flagGg = ImageAsset(name: "flag-gg") - static let flagGh = ImageAsset(name: "flag-gh") - static let flagGi = ImageAsset(name: "flag-gi") - static let flagGl = ImageAsset(name: "flag-gl") - static let flagGm = ImageAsset(name: "flag-gm") - static let flagGn = ImageAsset(name: "flag-gn") - static let flagGp = ImageAsset(name: "flag-gp") - static let flagGq = ImageAsset(name: "flag-gq") - static let flagGr = ImageAsset(name: "flag-gr") - static let flagGs = ImageAsset(name: "flag-gs") - static let flagGt = ImageAsset(name: "flag-gt") - static let flagGu = ImageAsset(name: "flag-gu") - static let flagGw = ImageAsset(name: "flag-gw") - static let flagGy = ImageAsset(name: "flag-gy") - static let flagHk = ImageAsset(name: "flag-hk") - static let flagHm = ImageAsset(name: "flag-hm") - static let flagHn = ImageAsset(name: "flag-hn") - static let flagHr = ImageAsset(name: "flag-hr") - static let flagHt = ImageAsset(name: "flag-ht") - static let flagHu = ImageAsset(name: "flag-hu") - static let flagId = ImageAsset(name: "flag-id") - static let flagIe = ImageAsset(name: "flag-ie") - static let flagIl = ImageAsset(name: "flag-il") - static let flagIm = ImageAsset(name: "flag-im") - static let flagIn = ImageAsset(name: "flag-in") - static let flagIo = ImageAsset(name: "flag-io") - static let flagIq = ImageAsset(name: "flag-iq") - static let flagIr = ImageAsset(name: "flag-ir") - static let flagIs = ImageAsset(name: "flag-is") - static let flagIt = ImageAsset(name: "flag-it") - static let flagJe = ImageAsset(name: "flag-je") - static let flagJm = ImageAsset(name: "flag-jm") - static let flagJo = ImageAsset(name: "flag-jo") - static let flagJp = ImageAsset(name: "flag-jp") - static let flagKe = ImageAsset(name: "flag-ke") - static let flagKg = ImageAsset(name: "flag-kg") - static let flagKh = ImageAsset(name: "flag-kh") - static let flagKi = ImageAsset(name: "flag-ki") - static let flagKm = ImageAsset(name: "flag-km") - static let flagKn = ImageAsset(name: "flag-kn") - static let flagKp = ImageAsset(name: "flag-kp") - static let flagKr = ImageAsset(name: "flag-kr") - static let flagKw = ImageAsset(name: "flag-kw") - static let flagKy = ImageAsset(name: "flag-ky") - static let flagKz = ImageAsset(name: "flag-kz") - static let flagLa = ImageAsset(name: "flag-la") - static let flagLb = ImageAsset(name: "flag-lb") - static let flagLc = ImageAsset(name: "flag-lc") - static let flagLi = ImageAsset(name: "flag-li") - static let flagLk = ImageAsset(name: "flag-lk") - static let flagLr = ImageAsset(name: "flag-lr") - static let flagLs = ImageAsset(name: "flag-ls") - static let flagLt = ImageAsset(name: "flag-lt") - static let flagLu = ImageAsset(name: "flag-lu") - static let flagLv = ImageAsset(name: "flag-lv") - static let flagLy = ImageAsset(name: "flag-ly") - static let flagMa = ImageAsset(name: "flag-ma") - static let flagMc = ImageAsset(name: "flag-mc") - static let flagMd = ImageAsset(name: "flag-md") - static let flagMe = ImageAsset(name: "flag-me") - static let flagMf = ImageAsset(name: "flag-mf") - static let flagMg = ImageAsset(name: "flag-mg") - static let flagMh = ImageAsset(name: "flag-mh") - static let flagMk = ImageAsset(name: "flag-mk") - static let flagMl = ImageAsset(name: "flag-ml") - static let flagMm = ImageAsset(name: "flag-mm") - static let flagMn = ImageAsset(name: "flag-mn") - static let flagMo = ImageAsset(name: "flag-mo") - static let flagMp = ImageAsset(name: "flag-mp") - static let flagMq = ImageAsset(name: "flag-mq") - static let flagMr = ImageAsset(name: "flag-mr") - static let flagMs = ImageAsset(name: "flag-ms") - static let flagMt = ImageAsset(name: "flag-mt") - static let flagMu = ImageAsset(name: "flag-mu") - static let flagMv = ImageAsset(name: "flag-mv") - static let flagMw = ImageAsset(name: "flag-mw") - static let flagMx = ImageAsset(name: "flag-mx") - static let flagMy = ImageAsset(name: "flag-my") - static let flagMz = ImageAsset(name: "flag-mz") - static let flagNa = ImageAsset(name: "flag-na") - static let flagNc = ImageAsset(name: "flag-nc") - static let flagNe = ImageAsset(name: "flag-ne") - static let flagNf = ImageAsset(name: "flag-nf") - static let flagNg = ImageAsset(name: "flag-ng") - static let flagNi = ImageAsset(name: "flag-ni") - static let flagNl = ImageAsset(name: "flag-nl") - static let flagNo = ImageAsset(name: "flag-no") - static let flagNp = ImageAsset(name: "flag-np") - static let flagNr = ImageAsset(name: "flag-nr") - static let flagNu = ImageAsset(name: "flag-nu") - static let flagNz = ImageAsset(name: "flag-nz") - static let flagOm = ImageAsset(name: "flag-om") - static let flagPa = ImageAsset(name: "flag-pa") - static let flagPe = ImageAsset(name: "flag-pe") - static let flagPf = ImageAsset(name: "flag-pf") - static let flagPg = ImageAsset(name: "flag-pg") - static let flagPh = ImageAsset(name: "flag-ph") - static let flagPk = ImageAsset(name: "flag-pk") - static let flagPl = ImageAsset(name: "flag-pl") - static let flagPm = ImageAsset(name: "flag-pm") - static let flagPn = ImageAsset(name: "flag-pn") - static let flagPr = ImageAsset(name: "flag-pr") - static let flagPs = ImageAsset(name: "flag-ps") - static let flagPt = ImageAsset(name: "flag-pt") - static let flagPw = ImageAsset(name: "flag-pw") - static let flagPy = ImageAsset(name: "flag-py") - static let flagQa = ImageAsset(name: "flag-qa") - static let flagRe = ImageAsset(name: "flag-re") - static let flagRo = ImageAsset(name: "flag-ro") - static let flagRs = ImageAsset(name: "flag-rs") - static let flagRu = ImageAsset(name: "flag-ru") - static let flagRw = ImageAsset(name: "flag-rw") - static let flagSa = ImageAsset(name: "flag-sa") - static let flagSb = ImageAsset(name: "flag-sb") - static let flagSc = ImageAsset(name: "flag-sc") - static let flagSd = ImageAsset(name: "flag-sd") - static let flagSe = ImageAsset(name: "flag-se") - static let flagSg = ImageAsset(name: "flag-sg") - static let flagSh = ImageAsset(name: "flag-sh") - static let flagSi = ImageAsset(name: "flag-si") - static let flagSj = ImageAsset(name: "flag-sj") - static let flagSk = ImageAsset(name: "flag-sk") - static let flagSl = ImageAsset(name: "flag-sl") - static let flagSm = ImageAsset(name: "flag-sm") - static let flagSn = ImageAsset(name: "flag-sn") - static let flagSo = ImageAsset(name: "flag-so") - static let flagSr = ImageAsset(name: "flag-sr") - static let flagSs = ImageAsset(name: "flag-ss") - static let flagSt = ImageAsset(name: "flag-st") - static let flagSv = ImageAsset(name: "flag-sv") - static let flagSx = ImageAsset(name: "flag-sx") - static let flagSy = ImageAsset(name: "flag-sy") - static let flagSz = ImageAsset(name: "flag-sz") - static let flagTc = ImageAsset(name: "flag-tc") - static let flagTd = ImageAsset(name: "flag-td") - static let flagTf = ImageAsset(name: "flag-tf") - static let flagTg = ImageAsset(name: "flag-tg") - static let flagTh = ImageAsset(name: "flag-th") - static let flagTj = ImageAsset(name: "flag-tj") - static let flagTk = ImageAsset(name: "flag-tk") - static let flagTl = ImageAsset(name: "flag-tl") - static let flagTm = ImageAsset(name: "flag-tm") - static let flagTn = ImageAsset(name: "flag-tn") - static let flagTo = ImageAsset(name: "flag-to") - static let flagTr = ImageAsset(name: "flag-tr") - static let flagTt = ImageAsset(name: "flag-tt") - static let flagTv = ImageAsset(name: "flag-tv") - static let flagTw = ImageAsset(name: "flag-tw") - static let flagTz = ImageAsset(name: "flag-tz") - static let flagUa = ImageAsset(name: "flag-ua") - static let flagUg = ImageAsset(name: "flag-ug") - static let flagUm = ImageAsset(name: "flag-um") - static let flagUn = ImageAsset(name: "flag-un") - static let flagUniversal = ImageAsset(name: "flag-universal") - static let flagUs = ImageAsset(name: "flag-us") - static let flagUy = ImageAsset(name: "flag-uy") - static let flagUz = ImageAsset(name: "flag-uz") - static let flagVa = ImageAsset(name: "flag-va") - static let flagVc = ImageAsset(name: "flag-vc") - static let flagVe = ImageAsset(name: "flag-ve") - static let flagVg = ImageAsset(name: "flag-vg") - static let flagVi = ImageAsset(name: "flag-vi") - static let flagVn = ImageAsset(name: "flag-vn") - static let flagVu = ImageAsset(name: "flag-vu") - static let flagWf = ImageAsset(name: "flag-wf") - static let flagWs = ImageAsset(name: "flag-ws") - static let flagYe = ImageAsset(name: "flag-ye") - static let flagYt = ImageAsset(name: "flag-yt") - static let flagZa = ImageAsset(name: "flag-za") - static let flagZm = ImageAsset(name: "flag-zm") - static let flagZw = ImageAsset(name: "flag-zw") - } - static let icon3dtConnect = ImageAsset(name: "icon-3dt-connect") - static let icon3dtDisconnect = ImageAsset(name: "icon-3dt-disconnect") - static let icon3dtSelectRegion = ImageAsset(name: "icon-3dt-select-region") - static let iconAbout1 = ImageAsset(name: "icon-about-1") - static let iconAccount = ImageAsset(name: "icon-account") - static let iconAdd = ImageAsset(name: "icon-add") - static let iconAlert = ImageAsset(name: "icon-alert") - static let iconAutomation = ImageAsset(name: "icon-automation") - static let iconClose = ImageAsset(name: "icon-close") - static let iconContact = ImageAsset(name: "icon-contact") - static let iconDip = ImageAsset(name: "icon-dip") - static let iconGeneral = ImageAsset(name: "icon-general") - static let iconGeoDarkSelected = ImageAsset(name: "icon-geo-dark-selected") - static let iconGeoDark = ImageAsset(name: "icon-geo-dark") - static let iconGeoSelected = ImageAsset(name: "icon-geo-selected") - static let iconGeo = ImageAsset(name: "icon-geo") - static let iconHomepage = ImageAsset(name: "icon-homepage") - static let iconLogout = ImageAsset(name: "icon-logout") - static let iconNetwork = ImageAsset(name: "icon-network") - static let iconPrivacy1 = ImageAsset(name: "icon-privacy-1") - static let iconProtocols = ImageAsset(name: "icon-protocols") - static let iconRegion = ImageAsset(name: "icon-region") - static let iconRemove = ImageAsset(name: "icon-remove") - static let iconSettings = ImageAsset(name: "icon-settings") - static let iconTrashDark = ImageAsset(name: "icon-trash-dark") - static let iconTrash = ImageAsset(name: "icon-trash") - static let iconWarning = ImageAsset(name: "icon-warning") - static let iconWifi = ImageAsset(name: "icon-wifi") - static let iconmenuAbout = ImageAsset(name: "iconmenu-about") - static let iconmenuPrivacy = ImageAsset(name: "iconmenu-privacy") - static let imageContentBlocker = ImageAsset(name: "image-content-blocker") - static let imagePurchaseSuccess = ImageAsset(name: "image-purchase-success") - static let imageRobot = ImageAsset(name: "image-robot") - static let imageVpnAllow = ImageAsset(name: "image-vpn-allow") - static let itemMenu = ImageAsset(name: "item-menu") - static let navLogoWhite = ImageAsset(name: "nav-logo-white") - static let navLogo = ImageAsset(name: "nav-logo") - static let offlineServerIcon = ImageAsset(name: "offline-server-icon") - static let shareIcon = ImageAsset(name: "share-icon") + static let closeIcon = ImageAsset(name: "close-icon") + static let imageAccountFailed = ImageAsset(name: "image-account-failed") + static let imageDocumentConsent = ImageAsset(name: "image-document-consent") + static let imageNoInternet = ImageAsset(name: "image-no-internet") + static let imagePurchaseSuccess = ImageAsset(name: "image-purchase-success") + static let imageReceiptBackground = ImageAsset(name: "image-receipt-background") + static let imageRedeemClaimed = ImageAsset(name: "image-redeem-claimed") + static let imageRedeemInvalid = ImageAsset(name: "image-redeem-invalid") + static let imageRedeemSuccess = ImageAsset(name: "image-redeem-success") + static let imageWalkthrough1 = ImageAsset(name: "image-walkthrough-1") + static let imageWalkthrough2 = ImageAsset(name: "image-walkthrough-2") + static let imageWalkthrough3 = ImageAsset(name: "image-walkthrough-3") + static let navLogo = ImageAsset(name: "nav-logo") + static let qrCode = ImageAsset(name: "qr-code") - // swiftlint:disable trailing_comma - static let allColors: [ColorAsset] = [ - ] - static let allImages: [ImageAsset] = [ - Cards.WireGuard.wgBackgroundDark, - Cards.WireGuard.wgBackgroundLight, - Cards.WireGuard.wgMain, - Piax.DarkMap.darkMap, - Piax.Dashboard.vpnButton, - Piax.Global.browserDarkInactive, - Piax.Global.browserLightInactive, - Piax.Global.dragDropIndicatorDark, - Piax.Global.dragDropIndicatorLight, - Piax.Global.eyeActiveDark, - Piax.Global.eyeActiveLight, - Piax.Global.eyeInactiveDark, - Piax.Global.eyeInactiveLight, - Piax.Global.favoriteGreen, - Piax.Global.favoriteSelected, - Piax.Global.favoriteUnselectedDark, - Piax.Global.favoriteUnselected, - Piax.Global.iconBack, - Piax.Global.iconEditTile, - Piax.Global.iconFilter, - Piax.Global.killswitchDarkActive, - Piax.Global.killswitchDarkInactive, - Piax.Global.killswitchLightInactive, - Piax.Global.nmtDarkActive, - Piax.Global.nmtDarkInactive, - Piax.Global.nmtLightActive, - Piax.Global.nmtLightInactive, - Piax.Global.regionSelected, - Piax.Global.themeDarkActive, - Piax.Global.themeDarkInactive, - Piax.Global.themeLightActive, - Piax.Global.themeLightInactive, - Piax.Global.trustedDarkIcon, - Piax.Global.trustedLightIcon, - Piax.Global.untrustedDarkIcon, - Piax.Global.untrustedLightIcon, - Piax.Nmt.iconAddRule, - Piax.Nmt.iconCustomWifiConnect, - Piax.Nmt.iconCustomWifiDisconnect, - Piax.Nmt.iconCustomWifiRetain, - Piax.Nmt.iconDisconnect, - Piax.Nmt.iconMobileDataConnect, - Piax.Nmt.iconMobileDataDisconnect, - Piax.Nmt.iconMobileDataRetain, - Piax.Nmt.iconNmtConnect, - Piax.Nmt.iconNmtWifi, - Piax.Nmt.iconOpenWifiConnect, - Piax.Nmt.iconOpenWifiDisconnect, - Piax.Nmt.iconOpenWifiRetain, - Piax.Nmt.iconOptions, - Piax.Nmt.iconRetain, - Piax.Nmt.iconSecureWifiConnect, - Piax.Nmt.iconSecureWifiDisconnect, - Piax.Nmt.iconSecureWifiRetain, - Piax.Nmt.iconSelect, - Piax.Regions.noResultsDark, - Piax.Regions.noResultsLight, - Piax.Settings.iconAbout, - Piax.Settings.iconAutomation, - Piax.Settings.iconGeneral, - Piax.Settings.iconNetwork, - Piax.Settings.iconPrivacy, - Piax.Settings.iconProtocols, - Piax.Splash.splash, - Piax.Tiles.ConnectionTile.iconAuthentication, - Piax.Tiles.ConnectionTile.iconEncryption, - Piax.Tiles.ConnectionTile.iconHandshake, - Piax.Tiles.ConnectionTile.iconPort, - Piax.Tiles.ConnectionTile.iconProtocol, - Piax.Tiles.ConnectionTile.iconSocket, - Piax.Tiles.ipTriangle, - Piax.Tiles.openTileDetails, - Piax.Tiles.quickConnectPlaceholderDark, - Piax.Tiles.quickConnectPlaceholderLight, - accessoryExpire, - accessorySelected, - buttonDown, - buttonUp, - copyIcon, - dipBadgeDark, - dipBadgeLight, - Flags.flagAd, - Flags.flagAe, - Flags.flagAf, - Flags.flagAg, - Flags.flagAi, - Flags.flagAl, - Flags.flagAm, - Flags.flagAo, - Flags.flagAq, - Flags.flagAr, - Flags.flagAs, - Flags.flagAt, - Flags.flagAu, - Flags.flagAw, - Flags.flagAx, - Flags.flagAz, - Flags.flagBa, - Flags.flagBb, - Flags.flagBd, - Flags.flagBe, - Flags.flagBf, - Flags.flagBg, - Flags.flagBh, - Flags.flagBi, - Flags.flagBj, - Flags.flagBl, - Flags.flagBm, - Flags.flagBn, - Flags.flagBo, - Flags.flagBq, - Flags.flagBr, - Flags.flagBs, - Flags.flagBt, - Flags.flagBv, - Flags.flagBw, - Flags.flagBy, - Flags.flagBz, - Flags.flagCa, - Flags.flagCc, - Flags.flagCd, - Flags.flagCf, - Flags.flagCg, - Flags.flagCh, - Flags.flagCi, - Flags.flagCk, - Flags.flagCl, - Flags.flagCm, - Flags.flagCn, - Flags.flagCo, - Flags.flagCr, - Flags.flagCu, - Flags.flagCv, - Flags.flagCw, - Flags.flagCx, - Flags.flagCy, - Flags.flagCz, - Flags.flagDe, - Flags.flagDj, - Flags.flagDk, - Flags.flagDm, - Flags.flagDo, - Flags.flagDz, - Flags.flagEc, - Flags.flagEe, - Flags.flagEg, - Flags.flagEh, - Flags.flagEr, - Flags.flagEsCt, - Flags.flagEs, - Flags.flagEt, - Flags.flagEu, - Flags.flagFi, - Flags.flagFj, - Flags.flagFk, - Flags.flagFm, - Flags.flagFo, - Flags.flagFr, - Flags.flagGa, - Flags.flagGbEng, - Flags.flagGbNir, - Flags.flagGbSct, - Flags.flagGbWls, - Flags.flagGb, - Flags.flagGd, - Flags.flagGe, - Flags.flagGf, - Flags.flagGg, - Flags.flagGh, - Flags.flagGi, - Flags.flagGl, - Flags.flagGm, - Flags.flagGn, - Flags.flagGp, - Flags.flagGq, - Flags.flagGr, - Flags.flagGs, - Flags.flagGt, - Flags.flagGu, - Flags.flagGw, - Flags.flagGy, - Flags.flagHk, - Flags.flagHm, - Flags.flagHn, - Flags.flagHr, - Flags.flagHt, - Flags.flagHu, - Flags.flagId, - Flags.flagIe, - Flags.flagIl, - Flags.flagIm, - Flags.flagIn, - Flags.flagIo, - Flags.flagIq, - Flags.flagIr, - Flags.flagIs, - Flags.flagIt, - Flags.flagJe, - Flags.flagJm, - Flags.flagJo, - Flags.flagJp, - Flags.flagKe, - Flags.flagKg, - Flags.flagKh, - Flags.flagKi, - Flags.flagKm, - Flags.flagKn, - Flags.flagKp, - Flags.flagKr, - Flags.flagKw, - Flags.flagKy, - Flags.flagKz, - Flags.flagLa, - Flags.flagLb, - Flags.flagLc, - Flags.flagLi, - Flags.flagLk, - Flags.flagLr, - Flags.flagLs, - Flags.flagLt, - Flags.flagLu, - Flags.flagLv, - Flags.flagLy, - Flags.flagMa, - Flags.flagMc, - Flags.flagMd, - Flags.flagMe, - Flags.flagMf, - Flags.flagMg, - Flags.flagMh, - Flags.flagMk, - Flags.flagMl, - Flags.flagMm, - Flags.flagMn, - Flags.flagMo, - Flags.flagMp, - Flags.flagMq, - Flags.flagMr, - Flags.flagMs, - Flags.flagMt, - Flags.flagMu, - Flags.flagMv, - Flags.flagMw, - Flags.flagMx, - Flags.flagMy, - Flags.flagMz, - Flags.flagNa, - Flags.flagNc, - Flags.flagNe, - Flags.flagNf, - Flags.flagNg, - Flags.flagNi, - Flags.flagNl, - Flags.flagNo, - Flags.flagNp, - Flags.flagNr, - Flags.flagNu, - Flags.flagNz, - Flags.flagOm, - Flags.flagPa, - Flags.flagPe, - Flags.flagPf, - Flags.flagPg, - Flags.flagPh, - Flags.flagPk, - Flags.flagPl, - Flags.flagPm, - Flags.flagPn, - Flags.flagPr, - Flags.flagPs, - Flags.flagPt, - Flags.flagPw, - Flags.flagPy, - Flags.flagQa, - Flags.flagRe, - Flags.flagRo, - Flags.flagRs, - Flags.flagRu, - Flags.flagRw, - Flags.flagSa, - Flags.flagSb, - Flags.flagSc, - Flags.flagSd, - Flags.flagSe, - Flags.flagSg, - Flags.flagSh, - Flags.flagSi, - Flags.flagSj, - Flags.flagSk, - Flags.flagSl, - Flags.flagSm, - Flags.flagSn, - Flags.flagSo, - Flags.flagSr, - Flags.flagSs, - Flags.flagSt, - Flags.flagSv, - Flags.flagSx, - Flags.flagSy, - Flags.flagSz, - Flags.flagTc, - Flags.flagTd, - Flags.flagTf, - Flags.flagTg, - Flags.flagTh, - Flags.flagTj, - Flags.flagTk, - Flags.flagTl, - Flags.flagTm, - Flags.flagTn, - Flags.flagTo, - Flags.flagTr, - Flags.flagTt, - Flags.flagTv, - Flags.flagTw, - Flags.flagTz, - Flags.flagUa, - Flags.flagUg, - Flags.flagUm, - Flags.flagUn, - Flags.flagUniversal, - Flags.flagUs, - Flags.flagUy, - Flags.flagUz, - Flags.flagVa, - Flags.flagVc, - Flags.flagVe, - Flags.flagVg, - Flags.flagVi, - Flags.flagVn, - Flags.flagVu, - Flags.flagWf, - Flags.flagWs, - Flags.flagYe, - Flags.flagYt, - Flags.flagZa, - Flags.flagZm, - Flags.flagZw, - icon3dtConnect, - icon3dtDisconnect, - icon3dtSelectRegion, - iconAbout1, - iconAccount, - iconAdd, - iconAlert, - iconAutomation, - iconClose, - iconContact, - iconDip, - iconGeneral, - iconGeoDarkSelected, - iconGeoDark, - iconGeoSelected, - iconGeo, - iconHomepage, - iconLogout, - iconNetwork, - iconPrivacy1, - iconProtocols, - iconRegion, - iconRemove, - iconSettings, - iconTrashDark, - iconTrash, - iconWarning, - iconWifi, - iconmenuAbout, - iconmenuPrivacy, - imageContentBlocker, - imagePurchaseSuccess, - imageRobot, - imageVpnAllow, - itemMenu, - navLogoWhite, - navLogo, - offlineServerIcon, - shareIcon, - ] - // swiftlint:enable trailing_comma - @available(*, deprecated, renamed: "allImages") - static let allValues: [AssetType] = allImages + // swiftlint:disable trailing_comma + static let allColors: [ColorAsset] = [ + ] + static let allImages: [ImageAsset] = [ + Piax.Global.centeredDarkMap, + Piax.Global.centeredLightMap, + Piax.Global.computerIcon, + Piax.Global.globeIcon, + Piax.Global.iconBack, + Piax.Global.iconCamera, + Piax.Global.iconClose, + Piax.Global.iconWarning, + Piax.Global.pagecontrolSelectedDot, + Piax.Global.pagecontrolUnselectedDot, + Piax.Global.planSelected, + Piax.Global.planUnselected, + Piax.Global.scrollableMapDark, + Piax.Global.scrollableMapLight, + Piax.Global.shieldIcon, + closeIcon, + imageAccountFailed, + imageDocumentConsent, + imageNoInternet, + imagePurchaseSuccess, + imageReceiptBackground, + imageRedeemClaimed, + imageRedeemInvalid, + imageRedeemSuccess, + imageWalkthrough1, + imageWalkthrough2, + imageWalkthrough3, + navLogo, + qrCode, + ] + // swiftlint:enable trailing_comma + @available(*, deprecated, renamed: "allImages") + static let allValues: [AssetType] = allImages + } } // swiftlint:enable identifier_name line_length nesting type_body_length type_name diff --git a/PIA VPN/SwiftGen+ScenesStoryboards.swift b/PIA VPN/SwiftGen+ScenesStoryboards.swift index 65b7d0076..2c426b9a4 100644 --- a/PIA VPN/SwiftGen+ScenesStoryboards.swift +++ b/PIA VPN/SwiftGen+ScenesStoryboards.swift @@ -1,29 +1,66 @@ // swiftlint:disable all -// Generated using SwiftGen, by O.Halligon — https://github.com/SwiftGen/SwiftGen +// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen // swiftlint:disable sorted_imports import Foundation +import PIALibrary import SideMenu import UIKit // swiftlint:disable superfluous_disable_command -// swiftlint:disable file_length +// swiftlint:disable file_length implicit_return // MARK: - Storyboard Scenes -// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name +// swiftlint:disable explicit_type_interface identifier_name line_length prefer_self_in_static_references +// swiftlint:disable type_body_length type_name internal enum StoryboardScene { internal enum Main: StoryboardType { internal static let storyboardName = "Main" internal static let initialScene = InitialSceneType(storyboard: Main.self) - internal static let sideMenuNavigationController = SceneType(storyboard: Main.self, identifier: "SideMenuNavigationController") + internal static let confirmVPNPlanViewController = SceneType(storyboard: Main.self, identifier: "ConfirmVPNPlanViewController") + + internal static let piaCardsViewController = SceneType(storyboard: Main.self, identifier: "PIACardsViewController") + + internal static let sideMenuNavigationController = SceneType(storyboard: Main.self, identifier: "SideMenuNavigationController") internal static let vpnPermissionViewController = SceneType(storyboard: Main.self, identifier: "VPNPermissionViewController") } + internal enum Signup: StoryboardType { + internal static let storyboardName = "Signup" + + internal static let initialScene = InitialSceneType(storyboard: Signup.self) + + internal static let confirmVPNPlanViewController = SceneType(storyboard: Signup.self, identifier: "ConfirmVPNPlanViewController") + + internal static let gdprViewController = SceneType(storyboard: Signup.self, identifier: "GDPRViewController") + + internal static let shareDataInformationViewController = SceneType(storyboard: Signup.self, identifier: "ShareDataInformationViewController") + + internal static let signupSuccessViewController = SceneType(storyboard: Signup.self, identifier: "SignupSuccessViewController") + } + internal enum Welcome: StoryboardType { + internal static let storyboardName = "Welcome" + + internal static let initialScene = InitialSceneType(storyboard: Welcome.self) + + internal static let getStartedViewController = SceneType(storyboard: Welcome.self, identifier: "GetStartedViewController") + + internal static let loginViewController = SceneType(storyboard: Welcome.self, identifier: "LoginViewController") + + internal static let magicLinkLoginViewController = SceneType(storyboard: Welcome.self, identifier: "MagicLinkLoginViewController") + + internal static let piaWelcomeViewController = SceneType(storyboard: Welcome.self, identifier: "PIAWelcomeViewController") + + internal static let purchaseViewController = SceneType(storyboard: Welcome.self, identifier: "PurchaseViewController") + + internal static let restoreSignupViewController = SceneType(storyboard: Welcome.self, identifier: "RestoreSignupViewController") + } } -// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name +// swiftlint:enable explicit_type_interface identifier_name line_length prefer_self_in_static_references +// swiftlint:enable type_body_length type_name // MARK: - Implementation Details @@ -34,7 +71,7 @@ internal protocol StoryboardType { internal extension StoryboardType { static var storyboard: UIStoryboard { let name = self.storyboardName - return UIStoryboard(name: name, bundle: Bundle(for: BundleToken.self)) + return UIStoryboard(name: name, bundle: BundleToken.bundle) } } @@ -49,6 +86,11 @@ internal struct SceneType { } return controller } + + @available(iOS 13.0, tvOS 13.0, *) + internal func instantiate(creator block: @escaping (NSCoder) -> T?) -> T { + return storyboard.storyboard.instantiateViewController(identifier: identifier, creator: block) + } } internal struct InitialSceneType { @@ -60,6 +102,24 @@ internal struct InitialSceneType { } return controller } + + @available(iOS 13.0, tvOS 13.0, *) + internal func instantiate(creator block: @escaping (NSCoder) -> T?) -> T { + guard let controller = storyboard.storyboard.instantiateInitialViewController(creator: block) else { + fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.") + } + return controller + } } -private final class BundleToken {} +// swiftlint:disable convenience_type +private final class BundleToken { + static let bundle: Bundle = { + #if SWIFT_PACKAGE + return Bundle.module + #else + return Bundle(for: BundleToken.self) + #endif + }() +} +// swiftlint:enable convenience_type diff --git a/PIA VPN/SwiftGen+SeguesStoryboards.swift b/PIA VPN/SwiftGen+SeguesStoryboards.swift index 15fbae565..9e8f6f66c 100644 --- a/PIA VPN/SwiftGen+SeguesStoryboards.swift +++ b/PIA VPN/SwiftGen+SeguesStoryboards.swift @@ -3,6 +3,7 @@ // swiftlint:disable sorted_imports import Foundation +import PIALibrary import SideMenu import UIKit @@ -39,6 +40,25 @@ internal enum StoryboardSegue { case trustedNetworksSegueIdentifier = "TrustedNetworksSegueIdentifier" case unwindContentBlockerSegueIdentifier = "UnwindContentBlockerSegueIdentifier" } + internal enum Signup: String, SegueType { + case failureSegueIdentifier = "FailureSegueIdentifier" + case internetUnreachableSegueIdentifier = "InternetUnreachableSegueIdentifier" + case presentGDPRTermsSegue = "PresentGDPRTermsSegue" + case successSegueIdentifier = "SuccessSegueIdentifier" + case successShowCredentialsSegueIdentifier = "SuccessShowCredentialsSegueIdentifier" + case unwindFailureSegueIdentifier = "UnwindFailureSegueIdentifier" + case unwindInternetUnreachableSegueIdentifier = "UnwindInternetUnreachableSegueIdentifier" + } + internal enum Welcome: String, SegueType { + case expiredAccountPurchaseSegue = "ExpiredAccountPurchaseSegue" + case loginAccountSegue = "LoginAccountSegue" + case purchaseVPNPlanSegue = "PurchaseVPNPlanSegue" + case restoreLoginPurchaseSegue = "RestoreLoginPurchaseSegue" + case restorePurchaseSegue = "RestorePurchaseSegue" + case signupViaPurchaseSegue = "SignupViaPurchaseSegue" + case signupViaRecoverSegue = "SignupViaRecoverSegue" + case signupViaRestoreSegue = "SignupViaRestoreSegue" + } } // swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name diff --git a/PIA VPN/SwiftGen+Strings.swift b/PIA VPN/SwiftGen+Strings.swift index 85d15c45b..777d2bc0f 100644 --- a/PIA VPN/SwiftGen+Strings.swift +++ b/PIA VPN/SwiftGen+Strings.swift @@ -3,1245 +3,1831 @@ import Foundation -// swiftlint:disable superfluous_disable_command file_length implicit_return +// swiftlint:disable superfluous_disable_command file_length implicit_return prefer_self_in_static_references // MARK: - Strings // swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length // swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces internal enum L10n { - - internal enum About { - /// VPN by Private Internet Access - internal static let app = L10n.tr("Localizable", "about.app") - /// This program uses the following components: - internal static let intro = L10n.tr("Localizable", "about.intro") - internal enum Accessibility { - internal enum Component { - /// Tap to read full license - internal static let expand = L10n.tr("Localizable", "about.accessibility.component.expand") + internal enum Localizable { + internal enum About { + /// VPN by Private Internet Access + internal static let app = L10n.tr("Localizable", "about.app", fallback: "VPN by Private Internet Access") + /// This program uses the following components: + internal static let intro = L10n.tr("Localizable", "about.intro", fallback: "This program uses the following components:") + internal enum Accessibility { + internal enum Component { + /// Tap to read full license + internal static let expand = L10n.tr("Localizable", "about.accessibility.component.expand", fallback: "Tap to read full license") + } } } - } - - internal enum Account { - /// Delete Account - internal static let delete = L10n.tr("Localizable", "account.delete") - /// Something went wrong. Please try logging in again - internal static let unauthorized = L10n.tr("Localizable", "account.unauthorized") - internal enum Delete { - internal enum Alert { - /// Something went wrong while deleting your account, please try again later. - internal static let failureMessage = L10n.tr("Localizable", "account.delete.alert.failureMessage") - /// Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active. - internal static let message = L10n.tr("Localizable", "account.delete.alert.message") - /// Are you sure? - internal static let title = L10n.tr("Localizable", "account.delete.alert.title") + internal enum Account { + /// Delete Account + internal static let delete = L10n.tr("Localizable", "account.delete", fallback: "Delete Account") + /// Something went wrong. Please try logging in again + internal static let unauthorized = L10n.tr("Localizable", "account.unauthorized", fallback: "Something went wrong. Please try logging in again") + internal enum Delete { + internal enum Alert { + /// Disable Now + internal static let cta1 = L10n.tr("Localizable", "dashboard.vpn.leakprotection.alert.cta1", fallback: "Disable Now") + /// Learn more + internal static let cta2 = L10n.tr("Localizable", "dashboard.vpn.leakprotection.alert.cta2", fallback: "Learn more") + /// Ignore + internal static let cta3 = L10n.tr("Localizable", "dashboard.vpn.leakprotection.alert.cta3", fallback: "Ignore") + /// To prevent data leaks, tap Disable Now to turn off “Allow access to devices on local network" and automatically reconnect. + internal static let message = L10n.tr("Localizable", "dashboard.vpn.leakprotection.alert.message", fallback: "To prevent data leaks, tap Disable Now to turn off “Allow access to devices on local network\" and automatically reconnect.") + /// Unsecured Wi-Fi detected + internal static let title = L10n.tr("Localizable", "dashboard.vpn.leakprotection.alert.title", fallback: "Unsecured Wi-Fi detected") + internal enum IKEV2 { + /// Switch now + internal static let cta1 = L10n.tr("Localizable", "dashboard.vpn.leakprotection.ikev2.alert.cta1", fallback: "Switch Now") + /// To prevent data leaks, tap Switch Now to change to the IKEv2 VPN protocol and automatically reconnect. + internal static let message = L10n.tr("Localizable", "dashboard.vpn.leakprotection.ikev2.alert.message", fallback: "To prevent data leaks, tap Switch Now to change to the IKEv2 VPN protocol and automatically reconnect.") + } + } } - } - internal enum Email { - /// Email - internal static let caption = L10n.tr("Localizable", "account.email.caption") - /// Email address - internal static let placeholder = L10n.tr("Localizable", "account.email.placeholder") - } - internal enum Error { - /// Your username or password is incorrect. - internal static let unauthorized = L10n.tr("Localizable", "account.error.unauthorized") - } - internal enum ExpiryDate { - /// Your plan has expired. - internal static let expired = L10n.tr("Localizable", "account.expiry_date.expired") - /// Your plan will expire on %@. - internal static func information(_ p1: Any) -> String { - return L10n.tr("Localizable", "account.expiry_date.information", String(describing: p1)) + internal enum Email { + /// Email + internal static let caption = L10n.tr("Localizable", "account.email.caption", fallback: "Email") + /// Email address + internal static let placeholder = L10n.tr("Localizable", "account.email.placeholder", fallback: "Email address") } - } - internal enum Other { - /// Get the Private Internet Access app for your other devices and use the above username and password to login and secure your connection. - internal static let footer = L10n.tr("Localizable", "account.other.footer") - } - internal enum Restore { - /// RESTORE PURCHASE - internal static let button = L10n.tr("Localizable", "account.restore.button") - /// If you renewed your plan but your account still says it's about to expire, you can restart the renewal from here. You will not be charged during this process. - internal static let description = L10n.tr("Localizable", "account.restore.description") - /// Restore uncredited purchase - internal static let title = L10n.tr("Localizable", "account.restore.title") - internal enum Failure { - /// No redeemable purchase was found for renewal. - internal static let message = L10n.tr("Localizable", "account.restore.failure.message") - /// Restore purchase - internal static let title = L10n.tr("Localizable", "account.restore.failure.title") + internal enum Error { + /// Your username or password is incorrect. + internal static let unauthorized = L10n.tr("Localizable", "account.error.unauthorized", fallback: "Your username or password is incorrect.") + } + internal enum ExpiryDate { + /// Your plan has expired. + internal static let expired = L10n.tr("Localizable", "account.expiry_date.expired", fallback: "Your plan has expired.") + /// Your plan will expire on %@. + internal static func information(_ p1: Any) -> String { + return L10n.tr("Localizable", "account.expiry_date.information", String(describing: p1), fallback: "Your plan will expire on %@.") + } } - } - internal enum Reveal { - /// Authenticate to reveal - internal static let prompt = L10n.tr("Localizable", "account.reveal.prompt") - } - internal enum Save { - /// Update email - internal static let item = L10n.tr("Localizable", "account.save.item") - /// Authenticate to save changes - internal static let prompt = L10n.tr("Localizable", "account.save.prompt") - /// Your email address has been saved. - internal static let success = L10n.tr("Localizable", "account.save.success") - } - internal enum Set { - internal enum Email { - /// There was an error adding email. Please try again later. - internal static let error = L10n.tr("Localizable", "account.set.email.error") + internal enum Other { + /// Get the Private Internet Access app for your other devices and use the above username and password to login and secure your connection. + internal static let footer = L10n.tr("Localizable", "account.other.footer", fallback: "Get the Private Internet Access app for your other devices and use the above username and password to login and secure your connection.") + } + internal enum Restore { + /// RESTORE PURCHASE + internal static let button = L10n.tr("Localizable", "account.restore.button", fallback: "RESTORE PURCHASE") + /// If you renewed your plan but your account still says it's about to expire, you can restart the renewal from here. You will not be charged during this process. + internal static let description = L10n.tr("Localizable", "account.restore.description", fallback: "If you renewed your plan but your account still says it's about to expire, you can restart the renewal from here. You will not be charged during this process.") + /// Restore uncredited purchase + internal static let title = L10n.tr("Localizable", "account.restore.title", fallback: "Restore uncredited purchase") + internal enum Failure { + /// No redeemable purchase was found for renewal. + internal static let message = L10n.tr("Localizable", "account.restore.failure.message", fallback: "No redeemable purchase was found for renewal.") + /// Restore purchase + internal static let title = L10n.tr("Localizable", "account.restore.failure.title", fallback: "Restore purchase") + } } - } - internal enum Subscriptions { - /// here. - internal static let linkMessage = L10n.tr("Localizable", "account.subscriptions.linkMessage") - /// You can manage your subscription from here. - internal static let message = L10n.tr("Localizable", "account.subscriptions.message") - /// Monthly plan - internal static let monthly = L10n.tr("Localizable", "account.subscriptions.monthly") - /// Trial plan - internal static let trial = L10n.tr("Localizable", "account.subscriptions.trial") - /// Yearly plan - internal static let yearly = L10n.tr("Localizable", "account.subscriptions.yearly") - internal enum Short { - /// Manage subscription - internal static let linkMessage = L10n.tr("Localizable", "account.subscriptions.short.linkMessage") - /// Manage subscription - internal static let message = L10n.tr("Localizable", "account.subscriptions.short.message") + internal enum Reveal { + /// Authenticate to reveal + internal static let prompt = L10n.tr("Localizable", "account.reveal.prompt", fallback: "Authenticate to reveal") + } + internal enum Save { + /// Update email + internal static let item = L10n.tr("Localizable", "account.save.item", fallback: "Update email") + /// Authenticate to save changes + internal static let prompt = L10n.tr("Localizable", "account.save.prompt", fallback: "Authenticate to save changes") + /// Your email address has been saved. + internal static let success = L10n.tr("Localizable", "account.save.success", fallback: "Your email address has been saved.") + } + internal enum Set { + internal enum Email { + /// There was an error adding email. Please try again later. + internal static let error = L10n.tr("Localizable", "account.set.email.error", fallback: "There was an error adding email. Please try again later.") + } } - } - internal enum Update { - internal enum Email { - internal enum Require { - internal enum Password { - /// Submit - internal static let button = L10n.tr("Localizable", "account.update.email.require.password.button") - /// For security reasons we require your PIA password to perform a change in your account. Please input your PIA password to proceed. - internal static let message = L10n.tr("Localizable", "account.update.email.require.password.message") - /// PIA Password Required - internal static let title = L10n.tr("Localizable", "account.update.email.require.password.title") + internal enum Subscriptions { + /// here. + internal static let linkMessage = L10n.tr("Localizable", "account.subscriptions.linkMessage", fallback: "here.") + /// You can manage your subscription from here. + internal static let message = L10n.tr("Localizable", "account.subscriptions.message", fallback: "You can manage your subscription from here.") + /// Monthly plan + internal static let monthly = L10n.tr("Localizable", "account.subscriptions.monthly", fallback: "Monthly plan") + /// Trial plan + internal static let trial = L10n.tr("Localizable", "account.subscriptions.trial", fallback: "Trial plan") + /// Yearly plan + internal static let yearly = L10n.tr("Localizable", "account.subscriptions.yearly", fallback: "Yearly plan") + internal enum Short { + /// Manage subscription + internal static let linkMessage = L10n.tr("Localizable", "account.subscriptions.short.linkMessage", fallback: "Manage subscription") + /// Manage subscription + internal static let message = L10n.tr("Localizable", "account.subscriptions.short.message", fallback: "Manage subscription") + } + } + internal enum Survey { + /// Want to help make PIA better? Let us know how we can improve! + /// Take The Survey + internal static let message = L10n.tr("Localizable", "account.survey.message", fallback: "Want to help make PIA better? Let us know how we can improve!\nTake The Survey") + /// Take The Survey + internal static let messageLink = L10n.tr("Localizable", "account.survey.messageLink", fallback: "Take The Survey") + } + internal enum Update { + internal enum Email { + internal enum Require { + internal enum Password { + /// Submit + internal static let button = L10n.tr("Localizable", "account.update.email.require.password.button", fallback: "Submit") + /// For security reasons we require your PIA password to perform a change in your account. Please input your PIA password to proceed. + internal static let message = L10n.tr("Localizable", "account.update.email.require.password.message", fallback: "For security reasons we require your PIA password to perform a change in your account. Please input your PIA password to proceed.") + /// PIA Password Required + internal static let title = L10n.tr("Localizable", "account.update.email.require.password.title", fallback: "PIA Password Required") + } } } } - } - internal enum Username { - /// Username - internal static let caption = L10n.tr("Localizable", "account.username.caption") - } - } - - internal enum Card { - internal enum Wireguard { - /// It's a new, more efficient VPN protocol that offers better performance, lower CPU usage and longer battery life. - internal static let description = L10n.tr("Localizable", "card.wireguard.description") - /// Try WireGuard® today! - internal static let title = L10n.tr("Localizable", "card.wireguard.title") - internal enum Cta { - /// Try WireGuard® now - internal static let activate = L10n.tr("Localizable", "card.wireguard.cta.activate") - /// Learn more - internal static let learn = L10n.tr("Localizable", "card.wireguard.cta.learn") - /// Open Settings - internal static let settings = L10n.tr("Localizable", "card.wireguard.cta.settings") + internal enum Username { + /// Username + internal static let caption = L10n.tr("Localizable", "account.username.caption", fallback: "Username") } - } - } - - internal enum ContentBlocker { - /// Safari Content Blocker - internal static let title = L10n.tr("Localizable", "content_blocker.title") - internal enum Body { - /// Please note: You do not need to be connected to the VPN for this Content Blocker to work, but it will only work while browsing with Safari. - internal static let footer = L10n.tr("Localizable", "content_blocker.body.footer") - /// To enable our Content Blocker for use with Safari please go to Settings > Safari, and under General touch Content Blockers toggle on PIA VPN. - internal static let subtitle = L10n.tr("Localizable", "content_blocker.body.subtitle") - } - } - - internal enum Dashboard { - internal enum Accessibility { - internal enum Vpn { - /// VPN Connection button - internal static let button = L10n.tr("Localizable", "dashboard.accessibility.vpn.button") - internal enum Button { - /// VPN Connection button. The VPN is currently disconnected - internal static let isOff = L10n.tr("Localizable", "dashboard.accessibility.vpn.button.isOff") - /// VPN Connection button. The VPN is currently connected - internal static let isOn = L10n.tr("Localizable", "dashboard.accessibility.vpn.button.isOn") + internal enum LeakProtectionAlert { + /// VPN Leak Protection update settings alert + internal static let title = L10n.tr("Localizable", "settings.application_settings.leak_protection.alert.title") } - } } - internal enum Connection { - internal enum Ip { - /// Internet unreachable - internal static let unreachable = L10n.tr("Localizable", "dashboard.connection.ip.unreachable") + internal enum Card { + internal enum Wireguard { + /// It's a new, more efficient VPN protocol that offers better performance, lower CPU usage and longer battery life. + internal static let description = L10n.tr("Localizable", "card.wireguard.description", fallback: "It's a new, more efficient VPN protocol that offers better performance, lower CPU usage and longer battery life.") + /// Try WireGuard® today! + internal static let title = L10n.tr("Localizable", "card.wireguard.title", fallback: "Try WireGuard® today!") + internal enum Cta { + /// Try WireGuard® now + internal static let activate = L10n.tr("Localizable", "card.wireguard.cta.activate", fallback: "Try WireGuard® now") + /// Learn more + internal static let learn = L10n.tr("Localizable", "card.wireguard.cta.learn", fallback: "Learn more") + /// Open Settings + internal static let settings = L10n.tr("Localizable", "card.wireguard.cta.settings", fallback: "Open Settings") + } } } internal enum ContentBlocker { - internal enum Intro { - /// This version replaces MACE with our Safari Content Blocker.\n\nCheck it out in the 'Settings' section. - internal static let message = L10n.tr("Localizable", "dashboard.content_blocker.intro.message") + /// Safari Content Blocker + internal static let title = L10n.tr("Localizable", "content_blocker.title", fallback: "Safari Content Blocker") + internal enum Body { + /// Please note: You do not need to be connected to the VPN for this Content Blocker to work, but it will only work while browsing with Safari. + internal static let footer = L10n.tr("Localizable", "content_blocker.body.footer", fallback: "Please note: You do not need to be connected to the VPN for this Content Blocker to work, but it will only work while browsing with Safari.") + /// To enable our Content Blocker for use with Safari please go to Settings > Safari, and under General touch Content Blockers toggle on PIA VPN. + internal static let subtitle = L10n.tr("Localizable", "content_blocker.body.subtitle", fallback: "To enable our Content Blocker for use with Safari please go to Settings > Safari, and under General touch Content Blockers toggle on PIA VPN.") } } - internal enum Vpn { - /// Changing region... - internal static let changingRegion = L10n.tr("Localizable", "dashboard.vpn.changing_region") - /// Connected to VPN - internal static let connected = L10n.tr("Localizable", "dashboard.vpn.connected") - /// Connecting... - internal static let connecting = L10n.tr("Localizable", "dashboard.vpn.connecting") - /// Disconnected - internal static let disconnected = L10n.tr("Localizable", "dashboard.vpn.disconnected") - /// Disconnecting... - internal static let disconnecting = L10n.tr("Localizable", "dashboard.vpn.disconnecting") - /// VPN: ON - internal static let on = L10n.tr("Localizable", "dashboard.vpn.on") - internal enum Disconnect { - /// This network is untrusted. Do you really want to disconnect the VPN? - internal static let untrusted = L10n.tr("Localizable", "dashboard.vpn.disconnect.untrusted") + internal enum Dashboard { + internal enum Accessibility { + internal enum Vpn { + /// VPN Connection button + internal static let button = L10n.tr("Localizable", "dashboard.accessibility.vpn.button", fallback: "VPN Connection button") + internal enum Button { + /// VPN Connection button. The VPN is currently disconnected + internal static let isOff = L10n.tr("Localizable", "dashboard.accessibility.vpn.button.isOff", fallback: "VPN Connection button. The VPN is currently disconnected") + /// VPN Connection button. The VPN is currently connected + internal static let isOn = L10n.tr("Localizable", "dashboard.accessibility.vpn.button.isOn", fallback: "VPN Connection button. The VPN is currently connected") + } + } } - } - } - - internal enum Dedicated { - internal enum Ip { - /// Are you sure you want to remove the selected region? - internal static let remove = L10n.tr("Localizable", "dedicated.ip.remove") - /// Dedicated IP - internal static let title = L10n.tr("Localizable", "dedicated.ip.title") - internal enum Activate { - internal enum Button { - /// Activate - internal static let title = L10n.tr("Localizable", "dedicated.ip.activate.button.title") + internal enum Connection { + internal enum Ip { + /// Internet unreachable + internal static let unreachable = L10n.tr("Localizable", "dashboard.connection.ip.unreachable", fallback: "Internet unreachable") } } - internal enum Activation { - /// Activate your Dedicated IP by pasting your token in the form below. If you've recently purchased a dedicated IP, you can generate the token by going to the PIA website. - internal static let description = L10n.tr("Localizable", "dedicated.ip.activation.description") + internal enum ContentBlocker { + internal enum Intro { + /// This version replaces MACE with our Safari Content Blocker. + /// + /// Check it out in the 'Settings' section. + internal static let message = L10n.tr("Localizable", "dashboard.content_blocker.intro.message", fallback: "This version replaces MACE with our Safari Content Blocker.\n\nCheck it out in the 'Settings' section.") + } } - internal enum Country { - internal enum Flag { - /// Country flag for %@ - internal static func accessibility(_ p1: Any) -> String { - return L10n.tr("Localizable", "dedicated.ip.country.flag.accessibility", String(describing: p1)) + internal enum Vpn { + /// Changing region... + internal static let changingRegion = L10n.tr("Localizable", "dashboard.vpn.changing_region", fallback: "Changing region...") + /// Connected to VPN + internal static let connected = L10n.tr("Localizable", "dashboard.vpn.connected", fallback: "Connected to VPN") + /// Connecting... + internal static let connecting = L10n.tr("Localizable", "dashboard.vpn.connecting", fallback: "Connecting...") + /// Disconnected + internal static let disconnected = L10n.tr("Localizable", "dashboard.vpn.disconnected", fallback: "Disconnected") + /// Disconnecting... + internal static let disconnecting = L10n.tr("Localizable", "dashboard.vpn.disconnecting", fallback: "Disconnecting...") + /// VPN: ON + internal static let on = L10n.tr("Localizable", "dashboard.vpn.on", fallback: "VPN: ON") + internal enum Disconnect { + /// This network is untrusted. Do you really want to disconnect the VPN? + internal static let untrusted = L10n.tr("Localizable", "dashboard.vpn.disconnect.untrusted", fallback: "This network is untrusted. Do you really want to disconnect the VPN?") + } + internal enum Leakprotection { + internal enum Alert { + /// Disable Now + internal static let cta1 = L10n.tr("Localizable", "dashboard.vpn.leakprotection.alert.cta1", fallback: "Disable Now") + /// Learn more + internal static let cta2 = L10n.tr("Localizable", "dashboard.vpn.leakprotection.alert.cta2", fallback: "Learn more") + /// Ignore + internal static let cta3 = L10n.tr("Localizable", "dashboard.vpn.leakprotection.alert.cta3", fallback: "Ignore") + /// To prevent data leaks, tap Disable Now to turn off “Allow access to devices on local network" and automatically reconnect. + internal static let message = L10n.tr("Localizable", "dashboard.vpn.leakprotection.alert.message", fallback: "To prevent data leaks, tap Disable Now to turn off “Allow access to devices on local network\" and automatically reconnect.") + /// Unsecured Wi-Fi detected + internal static let title = L10n.tr("Localizable", "dashboard.vpn.leakprotection.alert.title", fallback: "Unsecured Wi-Fi detected") + } + internal enum Ikev2 { + internal enum Alert { + /// Switch Now + internal static let cta1 = L10n.tr("Localizable", "dashboard.vpn.leakprotection.ikev2.alert.cta1", fallback: "Switch Now") + /// To prevent data leaks, tap Switch Now to change to the IKEv2 VPN protocol and automatically reconnect. + internal static let message = L10n.tr("Localizable", "dashboard.vpn.leakprotection.ikev2.alert.message", fallback: "To prevent data leaks, tap Switch Now to change to the IKEv2 VPN protocol and automatically reconnect.") + } } } } - internal enum Limit { - /// Secure your remote connections to any asset with a dedicated IP from a country of your choice. During your subscription, this IP will be yours and yours alone, protecting your data transfers with the strongest encryption out there. - internal static let title = L10n.tr("Localizable", "dedicated.ip.limit.title") - } - internal enum Message { - internal enum Error { - /// Too many failed token activation requests. Please try again after %@ second(s). - internal static func retryafter(_ p1: Any) -> String { - return L10n.tr("Localizable", "dedicated.ip.message.error.retryafter", String(describing: p1)) + } + internal enum Dedicated { + internal enum Ip { + /// Are you sure you want to remove the selected region? + internal static let remove = L10n.tr("Localizable", "dedicated.ip.remove", fallback: "Are you sure you want to remove the selected region?") + /// Dedicated IP + internal static let title = L10n.tr("Localizable", "dedicated.ip.title", fallback: "Dedicated IP") + internal enum Activate { + internal enum Button { + /// Activate + internal static let title = L10n.tr("Localizable", "dedicated.ip.activate.button.title", fallback: "Activate") } - /// Your token is expired. Please generate a new one from your Account page on the website. - internal static let token = L10n.tr("Localizable", "dedicated.ip.message.error.token") - } - internal enum Expired { - /// Your token is expired. Please generate a new one from your Account page on the website. - internal static let token = L10n.tr("Localizable", "dedicated.ip.message.expired.token") } - internal enum Incorrect { - /// Please make sure you have entered the token correctly - internal static let token = L10n.tr("Localizable", "dedicated.ip.message.incorrect.token") + internal enum Activation { + /// Activate your Dedicated IP by pasting your token in the form below. If you've recently purchased a dedicated IP, you can generate the token by going to the PIA website. + internal static let description = L10n.tr("Localizable", "dedicated.ip.activation.description", fallback: "Activate your Dedicated IP by pasting your token in the form below. If you've recently purchased a dedicated IP, you can generate the token by going to the PIA website.") } - internal enum Invalid { - /// Your token is invalid. Please make sure you have entered the token correctly. - internal static let token = L10n.tr("Localizable", "dedicated.ip.message.invalid.token") + internal enum Country { + internal enum Flag { + /// Country flag for %@ + internal static func accessibility(_ p1: Any) -> String { + return L10n.tr("Localizable", "dedicated.ip.country.flag.accessibility", String(describing: p1), fallback: "Country flag for %@") + } + } } - internal enum Ip { - /// Your dedicated IP was updated - internal static let updated = L10n.tr("Localizable", "dedicated.ip.message.ip.updated") + internal enum Limit { + /// Secure your remote connections to any asset with a dedicated IP from a country of your choice. During your subscription, this IP will be yours and yours alone, protecting your data transfers with the strongest encryption out there. + internal static let title = L10n.tr("Localizable", "dedicated.ip.limit.title", fallback: "Secure your remote connections to any asset with a dedicated IP from a country of your choice. During your subscription, this IP will be yours and yours alone, protecting your data transfers with the strongest encryption out there.") } - internal enum Token { - /// Your dedicated IP will expire soon. Get a new one - internal static let willexpire = L10n.tr("Localizable", "dedicated.ip.message.token.willexpire") - internal enum Willexpire { - /// Get a new one - internal static let link = L10n.tr("Localizable", "dedicated.ip.message.token.willexpire.link") + internal enum Message { + internal enum Error { + /// Too many failed token activation requests. Please try again after %@ second(s). + internal static func retryafter(_ p1: Any) -> String { + return L10n.tr("Localizable", "dedicated.ip.message.error.retryafter", String(describing: p1), fallback: "Too many failed token activation requests. Please try again after %@ second(s).") + } + /// Your token is expired. Please generate a new one from your Account page on the website. + internal static let token = L10n.tr("Localizable", "dedicated.ip.message.error.token", fallback: "Your token is expired. Please generate a new one from your Account page on the website.") + } + internal enum Expired { + /// Your token is expired. Please generate a new one from your Account page on the website. + internal static let token = L10n.tr("Localizable", "dedicated.ip.message.expired.token", fallback: "Your token is expired. Please generate a new one from your Account page on the website.") + } + internal enum Incorrect { + /// Please make sure you have entered the token correctly + internal static let token = L10n.tr("Localizable", "dedicated.ip.message.incorrect.token", fallback: "Please make sure you have entered the token correctly") + } + internal enum Invalid { + /// Your token is invalid. Please make sure you have entered the token correctly. + internal static let token = L10n.tr("Localizable", "dedicated.ip.message.invalid.token", fallback: "Your token is invalid. Please make sure you have entered the token correctly.") + } + internal enum Ip { + /// Your dedicated IP was updated + internal static let updated = L10n.tr("Localizable", "dedicated.ip.message.ip.updated", fallback: "Your dedicated IP was updated") + } + internal enum Token { + /// Your dedicated IP will expire soon. Get a new one + internal static let willexpire = L10n.tr("Localizable", "dedicated.ip.message.token.willexpire", fallback: "Your dedicated IP will expire soon. Get a new one") + internal enum Willexpire { + /// Get a new one + internal static let link = L10n.tr("Localizable", "dedicated.ip.message.token.willexpire.link", fallback: "Get a new one") + } + } + internal enum Valid { + /// Your Dedicated IP has been activated successfully. It will be available in your Region selection list. + internal static let token = L10n.tr("Localizable", "dedicated.ip.message.valid.token", fallback: "Your Dedicated IP has been activated successfully. It will be available in your Region selection list.") } } - internal enum Valid { - /// Your Dedicated IP has been activated successfully. It will be available in your Region selection list. - internal static let token = L10n.tr("Localizable", "dedicated.ip.message.valid.token") + internal enum Plural { + /// Your Dedicated IPs + internal static let title = L10n.tr("Localizable", "dedicated.ip.plural.title", fallback: "Your Dedicated IPs") } - } - internal enum Plural { - /// Your Dedicated IPs - internal static let title = L10n.tr("Localizable", "dedicated.ip.plural.title") - } - internal enum Token { - internal enum Textfield { - /// The textfield to type the Dedicated IP token - internal static let accessibility = L10n.tr("Localizable", "dedicated.ip.token.textfield.accessibility") - /// Paste in your token here - internal static let placeholder = L10n.tr("Localizable", "dedicated.ip.token.textfield.placeholder") + internal enum Token { + internal enum Textfield { + /// The textfield to type the Dedicated IP token + internal static let accessibility = L10n.tr("Localizable", "dedicated.ip.token.textfield.accessibility", fallback: "The textfield to type the Dedicated IP token") + /// Paste in your token here + internal static let placeholder = L10n.tr("Localizable", "dedicated.ip.token.textfield.placeholder", fallback: "Paste in your token here") + } } } } - } - - internal enum Expiration { - /// Your subscription expires soon. Renew to stay protected. - internal static let message = L10n.tr("Localizable", "expiration.message") - /// Renewal - internal static let title = L10n.tr("Localizable", "expiration.title") - } - - internal enum Friend { - internal enum Referrals { - /// Full name - internal static let fullName = L10n.tr("Localizable", "friend.referrals.fullName") - /// Signed up - internal static let signedup = L10n.tr("Localizable", "friend.referrals.signedup") - /// Refer a Friend - internal static let title = L10n.tr("Localizable", "friend.referrals.title") - internal enum Days { - /// Free days acquired - internal static let acquired = L10n.tr("Localizable", "friend.referrals.days.acquired") - /// %d days - internal static func number(_ p1: Int) -> String { - return L10n.tr("Localizable", "friend.referrals.days.number", p1) + internal enum Expiration { + /// Your subscription expires soon. Renew to stay protected. + internal static let message = L10n.tr("Localizable", "expiration.message", fallback: "Your subscription expires soon. Renew to stay protected.") + /// Renewal + internal static let title = L10n.tr("Localizable", "expiration.title", fallback: "Renewal") + } + internal enum Friend { + internal enum Referrals { + /// Full name + internal static let fullName = L10n.tr("Localizable", "friend.referrals.fullName", fallback: "Full name") + /// Signed up + internal static let signedup = L10n.tr("Localizable", "friend.referrals.signedup", fallback: "Signed up") + /// Refer a Friend + internal static let title = L10n.tr("Localizable", "friend.referrals.title", fallback: "Refer a Friend") + internal enum Days { + /// Free days acquired + internal static let acquired = L10n.tr("Localizable", "friend.referrals.days.acquired", fallback: "Free days acquired") + /// %d days + internal static func number(_ p1: Int) -> String { + return L10n.tr("Localizable", "friend.referrals.days.number", p1, fallback: "%d days") + } } - } - internal enum Description { - /// REFER A FRIEND. GET 30 DAYS FREE. - internal static let short = L10n.tr("Localizable", "friend.referrals.description.short") - } - internal enum Email { - /// Invalid email. Please try again. - internal static let validation = L10n.tr("Localizable", "friend.referrals.email.validation") - } - internal enum Family { - internal enum Friends { - /// Family and Friends Referral Program - internal static let program = L10n.tr("Localizable", "friend.referrals.family.friends.program") + internal enum Description { + /// REFER A FRIEND. GET 30 DAYS FREE. + internal static let short = L10n.tr("Localizable", "friend.referrals.description.short", fallback: "REFER A FRIEND. GET 30 DAYS FREE.") + } + internal enum Email { + /// Invalid email. Please try again. + internal static let validation = L10n.tr("Localizable", "friend.referrals.email.validation", fallback: "Invalid email. Please try again.") } - } - internal enum Friends { internal enum Family { - /// Refer your friends and family. For every sign up we’ll give you both 30 days free. - internal static let title = L10n.tr("Localizable", "friend.referrals.friends.family.title") + internal enum Friends { + /// Family and Friends Referral Program + internal static let program = L10n.tr("Localizable", "friend.referrals.family.friends.program", fallback: "Family and Friends Referral Program") + } } - } - internal enum Invitation { - /// By sending this invitation, I agree to all of the terms and conditions of the Family and Friends Referral Program. - internal static let terms = L10n.tr("Localizable", "friend.referrals.invitation.terms") - } - internal enum Invite { - /// Could not resend invite. Try again later. - internal static let error = L10n.tr("Localizable", "friend.referrals.invite.error") - /// Invite sent successfully - internal static let success = L10n.tr("Localizable", "friend.referrals.invite.success") - } - internal enum Invites { - /// You have sent %d invites - internal static func number(_ p1: Int) -> String { - return L10n.tr("Localizable", "friend.referrals.invites.number", p1) + internal enum Friends { + internal enum Family { + /// Refer your friends and family. For every sign up we’ll give you both 30 days free. + internal static let title = L10n.tr("Localizable", "friend.referrals.friends.family.title", fallback: "Refer your friends and family. For every sign up we’ll give you both 30 days free. ") + } } - internal enum Sent { - /// Invites sent - internal static let title = L10n.tr("Localizable", "friend.referrals.invites.sent.title") + internal enum Invitation { + /// By sending this invitation, I agree to all of the terms and conditions of the Family and Friends Referral Program. + internal static let terms = L10n.tr("Localizable", "friend.referrals.invitation.terms", fallback: "By sending this invitation, I agree to all of the terms and conditions of the Family and Friends Referral Program.") } - } - internal enum Pending { - /// %d pending invites - internal static func invites(_ p1: Int) -> String { - return L10n.tr("Localizable", "friend.referrals.pending.invites", p1) + internal enum Invite { + /// Could not resend invite. Try again later. + internal static let error = L10n.tr("Localizable", "friend.referrals.invite.error", fallback: "Could not resend invite. Try again later.") + /// Invite sent successfully + internal static let success = L10n.tr("Localizable", "friend.referrals.invite.success", fallback: "Invite sent successfully") } internal enum Invites { - /// Pending invites - internal static let title = L10n.tr("Localizable", "friend.referrals.pending.invites.title") + /// You have sent %d invites + internal static func number(_ p1: Int) -> String { + return L10n.tr("Localizable", "friend.referrals.invites.number", p1, fallback: "You have sent %d invites") + } + internal enum Sent { + /// Invites sent + internal static let title = L10n.tr("Localizable", "friend.referrals.invites.sent.title", fallback: "Invites sent") + } } - } - internal enum Privacy { - /// Please note, for privacy reasons, all invites older than 30 days will be deleted. - internal static let note = L10n.tr("Localizable", "friend.referrals.privacy.note") - } - internal enum Reward { - /// Reward given - internal static let given = L10n.tr("Localizable", "friend.referrals.reward.given") - } - internal enum Send { - /// Send invite - internal static let invite = L10n.tr("Localizable", "friend.referrals.send.invite") - } - internal enum Share { - /// Share your unique referral link - internal static let link = L10n.tr("Localizable", "friend.referrals.share.link") - internal enum Link { - /// By sharing this link, you agree to all of the terms and conditions of the Family and Friends Referral Program. - internal static let terms = L10n.tr("Localizable", "friend.referrals.share.link.terms") + internal enum Pending { + /// %d pending invites + internal static func invites(_ p1: Int) -> String { + return L10n.tr("Localizable", "friend.referrals.pending.invites", p1, fallback: "%d pending invites") + } + internal enum Invites { + /// Pending invites + internal static let title = L10n.tr("Localizable", "friend.referrals.pending.invites.title", fallback: "Pending invites") + } } - } - internal enum Signups { - /// %d signups - internal static func number(_ p1: Int) -> String { - return L10n.tr("Localizable", "friend.referrals.signups.number", p1) + internal enum Privacy { + /// Please note, for privacy reasons, all invites older than 30 days will be deleted. + internal static let note = L10n.tr("Localizable", "friend.referrals.privacy.note", fallback: "Please note, for privacy reasons, all invites older than 30 days will be deleted.") } - } - internal enum View { - internal enum Invites { - /// View invites sent - internal static let sent = L10n.tr("Localizable", "friend.referrals.view.invites.sent") + internal enum Reward { + /// Reward given + internal static let given = L10n.tr("Localizable", "friend.referrals.reward.given", fallback: "Reward given") + } + internal enum Send { + /// Send invite + internal static let invite = L10n.tr("Localizable", "friend.referrals.send.invite", fallback: "Send invite") + } + internal enum Share { + /// Share your unique referral link + internal static let link = L10n.tr("Localizable", "friend.referrals.share.link", fallback: "Share your unique referral link") + internal enum Link { + /// By sharing this link, you agree to all of the terms and conditions of the Family and Friends Referral Program. + internal static let terms = L10n.tr("Localizable", "friend.referrals.share.link.terms", fallback: "By sharing this link, you agree to all of the terms and conditions of the Family and Friends Referral Program.") + } + } + internal enum Signups { + /// %d signups + internal static func number(_ p1: Int) -> String { + return L10n.tr("Localizable", "friend.referrals.signups.number", p1, fallback: "%d signups") + } + } + internal enum View { + internal enum Invites { + /// View invites sent + internal static let sent = L10n.tr("Localizable", "friend.referrals.view.invites.sent", fallback: "View invites sent") + } } } } - } - - internal enum Gdpr { - internal enum Accept { - internal enum Button { - /// Agree and continue - internal static let title = L10n.tr("Localizable", "gdpr.accept.button.title") - } - } - internal enum Collect { - internal enum Data { - /// E-mail Address for the purposes of account management and protection from abuse.\n\nE-mail address is used to send subscription information, payment confirmations, customer correspondence, and Private Internet Access promotional offers only. - internal static let description = L10n.tr("Localizable", "gdpr.collect.data.description") - /// Personal information we collect - internal static let title = L10n.tr("Localizable", "gdpr.collect.data.title") + internal enum Gdpr { + internal enum Accept { + internal enum Button { + /// Agree and continue + internal static let title = L10n.tr("Localizable", "gdpr.accept.button.title", fallback: "Agree and continue") + } } - } - } - - internal enum Global { - /// Add - internal static let add = L10n.tr("Localizable", "global.add") - /// Automatic - internal static let automatic = L10n.tr("Localizable", "global.automatic") - /// Cancel - internal static let cancel = L10n.tr("Localizable", "global.cancel") - /// Clear - internal static let clear = L10n.tr("Localizable", "global.clear") - /// Close - internal static let close = L10n.tr("Localizable", "global.close") - /// Copied to clipboard - internal static let copied = L10n.tr("Localizable", "global.copied") - /// Copy - internal static let copy = L10n.tr("Localizable", "global.copy") - /// Disable - internal static let disable = L10n.tr("Localizable", "global.disable") - /// Disabled - internal static let disabled = L10n.tr("Localizable", "global.disabled") - /// Edit - internal static let edit = L10n.tr("Localizable", "global.edit") - /// Empty - internal static let empty = L10n.tr("Localizable", "global.empty") - /// Enable - internal static let enable = L10n.tr("Localizable", "global.enable") - /// Enabled - internal static let enabled = L10n.tr("Localizable", "global.enabled") - /// Error - internal static let error = L10n.tr("Localizable", "global.error") - /// No - internal static let no = L10n.tr("Localizable", "global.no") - /// OK - internal static let ok = L10n.tr("Localizable", "global.ok") - /// Optional - internal static let `optional` = L10n.tr("Localizable", "global.optional") - /// or - internal static let or = L10n.tr("Localizable", "global.or") - /// Remove - internal static let remove = L10n.tr("Localizable", "global.remove") - /// Required - internal static let `required` = L10n.tr("Localizable", "global.required") - /// Share - internal static let share = L10n.tr("Localizable", "global.share") - /// No internet connection found. Please confirm that you have an internet connection. - internal static let unreachable = L10n.tr("Localizable", "global.unreachable") - /// Update - internal static let update = L10n.tr("Localizable", "global.update") - /// Version - internal static let version = L10n.tr("Localizable", "global.version") - /// Yes - internal static let yes = L10n.tr("Localizable", "global.yes") - internal enum General { - /// General Settings - internal static let settings = L10n.tr("Localizable", "global.general.settings") - } - internal enum Row { - /// Row selection - internal static let selection = L10n.tr("Localizable", "global.row.selection") - } - internal enum Vpn { - /// VPN Settings - internal static let settings = L10n.tr("Localizable", "global.vpn.settings") - } - } - - internal enum Hotspothelper { - internal enum Display { - /// 🔒 Activate VPN WiFi Protection in PIA Settings to secure this connection. - internal static let name = L10n.tr("Localizable", "hotspothelper.display.name") - internal enum Protected { - /// 🔒 PIA VPN WiFi Protection Enabled - We got your back. - internal static let name = L10n.tr("Localizable", "hotspothelper.display.protected.name") + internal enum Collect { + internal enum Data { + /// E-mail Address for the purposes of account management and protection from abuse. + /// + /// E-mail address is used to send subscription information, payment confirmations, customer correspondence, and Private Internet Access promotional offers only. + internal static let description = L10n.tr("Localizable", "gdpr.collect.data.description", fallback: "E-mail Address for the purposes of account management and protection from abuse.\n\nE-mail address is used to send subscription information, payment confirmations, customer correspondence, and Private Internet Access promotional offers only.") + /// Personal information we collect + internal static let title = L10n.tr("Localizable", "gdpr.collect.data.title", fallback: "Personal information we collect") + } } } - } - - internal enum Inapp { - internal enum Messages { - internal enum Settings { - /// Settings have been updated - internal static let updated = L10n.tr("Localizable", "inapp.messages.settings.updated") + internal enum Global { + /// Add + internal static let add = L10n.tr("Localizable", "global.add", fallback: "Add") + /// Automatic + internal static let automatic = L10n.tr("Localizable", "global.automatic", fallback: "Automatic") + /// Cancel + internal static let cancel = L10n.tr("Localizable", "global.cancel", fallback: "Cancel") + /// Clear + internal static let clear = L10n.tr("Localizable", "global.clear", fallback: "Clear") + /// Close + internal static let close = L10n.tr("Localizable", "global.close", fallback: "Close") + /// Copied to clipboard + internal static let copied = L10n.tr("Localizable", "global.copied", fallback: "Copied to clipboard") + /// Copy + internal static let copy = L10n.tr("Localizable", "global.copy", fallback: "Copy") + /// Disable + internal static let disable = L10n.tr("Localizable", "global.disable", fallback: "Disable") + /// Disabled + internal static let disabled = L10n.tr("Localizable", "global.disabled", fallback: "Disabled") + /// Edit + internal static let edit = L10n.tr("Localizable", "global.edit", fallback: "Edit") + /// Empty + internal static let empty = L10n.tr("Localizable", "global.empty", fallback: "Empty") + /// Enable + internal static let enable = L10n.tr("Localizable", "global.enable", fallback: "Enable") + /// Enabled + internal static let enabled = L10n.tr("Localizable", "global.enabled", fallback: "Enabled") + /// Error + internal static let error = L10n.tr("Localizable", "global.error", fallback: "Error") + /// No + internal static let no = L10n.tr("Localizable", "global.no", fallback: "No") + /// OK + internal static let ok = L10n.tr("Localizable", "global.ok", fallback: "OK") + /// Optional + internal static let `optional` = L10n.tr("Localizable", "global.optional", fallback: "Optional") + /// or + internal static let or = L10n.tr("Localizable", "global.or", fallback: "or") + /// Remove + internal static let remove = L10n.tr("Localizable", "global.remove", fallback: "Remove") + /// Required + internal static let `required` = L10n.tr("Localizable", "global.required", fallback: "Required") + /// Share + internal static let share = L10n.tr("Localizable", "global.share", fallback: "Share") + /// No internet connection found. Please confirm that you have an internet connection. + internal static let unreachable = L10n.tr("Localizable", "global.unreachable", fallback: "No internet connection found. Please confirm that you have an internet connection.") + /// Update + internal static let update = L10n.tr("Localizable", "global.update", fallback: "Update") + /// Version + internal static let version = L10n.tr("Localizable", "global.version", fallback: "Version") + /// Yes + internal static let yes = L10n.tr("Localizable", "global.yes", fallback: "Yes") + internal enum General { + /// General Settings + internal static let settings = L10n.tr("Localizable", "global.general.settings", fallback: "General Settings") + } + internal enum Row { + /// Row selection + internal static let selection = L10n.tr("Localizable", "global.row.selection", fallback: "Row selection") } - internal enum Toggle { - /// Show Service Communication Messages - internal static let title = L10n.tr("Localizable", "inapp.messages.toggle.title") + internal enum Vpn { + /// VPN Settings + internal static let settings = L10n.tr("Localizable", "global.vpn.settings", fallback: "VPN Settings") } } - } - - internal enum Menu { - internal enum Accessibility { - /// Menu - internal static let item = L10n.tr("Localizable", "menu.accessibility.item") - /// Logged in as %@ - internal static func loggedAs(_ p1: Any) -> String { - return L10n.tr("Localizable", "menu.accessibility.logged_as", String(describing: p1)) - } - internal enum Edit { - /// Edit - internal static let tile = L10n.tr("Localizable", "menu.accessibility.edit.tile") + internal enum Hotspothelper { + internal enum Display { + /// 🔒 Activate VPN WiFi Protection in PIA Settings to secure this connection. + internal static let name = L10n.tr("Localizable", "hotspothelper.display.name", fallback: "🔒 Activate VPN WiFi Protection in PIA Settings to secure this connection.") + internal enum Protected { + /// 🔒 PIA VPN WiFi Protection Enabled - We got your back. + internal static let name = L10n.tr("Localizable", "hotspothelper.display.protected.name", fallback: "🔒 PIA VPN WiFi Protection Enabled - We got your back.") + } } } - internal enum Expiration { - /// %d days - internal static func days(_ p1: Int) -> String { - return L10n.tr("Localizable", "menu.expiration.days", p1) - } - /// Subscription expires in - internal static let expiresIn = L10n.tr("Localizable", "menu.expiration.expires_in") - /// %d hours - internal static func hours(_ p1: Int) -> String { - return L10n.tr("Localizable", "menu.expiration.hours", p1) - } - /// one hour - internal static let oneHour = L10n.tr("Localizable", "menu.expiration.one_hour") - /// UPGRADE ACCOUNT - internal static let upgrade = L10n.tr("Localizable", "menu.expiration.upgrade") - } - internal enum Item { - /// About - internal static let about = L10n.tr("Localizable", "menu.item.about") - /// Account - internal static let account = L10n.tr("Localizable", "menu.item.account") - /// Log out - internal static let logout = L10n.tr("Localizable", "menu.item.logout") - /// Region selection - internal static let region = L10n.tr("Localizable", "menu.item.region") - /// Settings - internal static let settings = L10n.tr("Localizable", "menu.item.settings") - internal enum Web { - /// Home page - internal static let home = L10n.tr("Localizable", "menu.item.web.home") - /// Privacy policy - internal static let privacy = L10n.tr("Localizable", "menu.item.web.privacy") - /// Support - internal static let support = L10n.tr("Localizable", "menu.item.web.support") + internal enum Inapp { + internal enum Messages { + internal enum Settings { + /// Settings have been updated + internal static let updated = L10n.tr("Localizable", "inapp.messages.settings.updated", fallback: "Settings have been updated") + } + internal enum Toggle { + /// Show Service Communication Messages + internal static let title = L10n.tr("Localizable", "inapp.messages.toggle.title", fallback: "Show Service Communication Messages") + } } } - internal enum Logout { - /// Log out - internal static let confirm = L10n.tr("Localizable", "menu.logout.confirm") - /// Logging out will disable the VPN and leave you unprotected. - internal static let message = L10n.tr("Localizable", "menu.logout.message") - /// Log out - internal static let title = L10n.tr("Localizable", "menu.logout.title") - } - internal enum Renewal { - /// Purchase - internal static let purchase = L10n.tr("Localizable", "menu.renewal.purchase") - /// Renew - internal static let renew = L10n.tr("Localizable", "menu.renewal.renew") - /// Renewal - internal static let title = L10n.tr("Localizable", "menu.renewal.title") - internal enum Message { - /// Trial accounts are not eligible for renewal. Please purchase a new account upon expiry to continue service. - internal static let trial = L10n.tr("Localizable", "menu.renewal.message.trial") - /// Apple servers currently unavailable. Please try again later. - internal static let unavailable = L10n.tr("Localizable", "menu.renewal.message.unavailable") - /// Please use our website to renew your subscription. - internal static let website = L10n.tr("Localizable", "menu.renewal.message.website") + internal enum LocalNotification { + internal enum NonCompliantWifi { + /// Tap here to secure your device + internal static let text = L10n.tr("Localizable", "local_notification.non_compliant_wifi.text", fallback: "Tap here to secure your device") + /// Unsecured Wi-Fi: %@ + internal static func title(_ p1: Any) -> String { + return L10n.tr("Localizable", "local_notification.non_compliant_wifi.title", String(describing: p1), fallback: "Unsecured Wi-Fi: %@") + } } } - } - - internal enum Network { - internal enum Management { - internal enum Tool { - /// Your automation settings are configured to keep the VPN disconnected under the current network conditions. - internal static let alert = L10n.tr("Localizable", "network.management.tool.alert") - /// Disable Automation - internal static let disable = L10n.tr("Localizable", "network.management.tool.disable") - /// Manage Automation - internal static let title = L10n.tr("Localizable", "network.management.tool.title") - internal enum Add { - /// Add new rule - internal static let rule = L10n.tr("Localizable", "network.management.tool.add.rule") - } - internal enum Always { - /// Always connect VPN - internal static let connect = L10n.tr("Localizable", "network.management.tool.always.connect") - /// Always disconnect VPN - internal static let disconnect = L10n.tr("Localizable", "network.management.tool.always.disconnect") - } - internal enum Choose { - /// Choose a WiFi network to add a new rule. - internal static let wifi = L10n.tr("Localizable", "network.management.tool.choose.wifi") + internal enum Menu { + internal enum Accessibility { + /// Menu + internal static let item = L10n.tr("Localizable", "menu.accessibility.item", fallback: "Menu") + /// Logged in as %@ + internal static func loggedAs(_ p1: Any) -> String { + return L10n.tr("Localizable", "menu.accessibility.logged_as", String(describing: p1), fallback: "Logged in as %@") } - internal enum Enable { - /// Enable Automation - internal static let automation = L10n.tr("Localizable", "network.management.tool.enable.automation") + internal enum Edit { + /// Edit + internal static let tile = L10n.tr("Localizable", "menu.accessibility.edit.tile", fallback: "Edit") } - internal enum Mobile { - /// Mobile data - internal static let data = L10n.tr("Localizable", "network.management.tool.mobile.data") + } + internal enum Expiration { + /// %d days + internal static func days(_ p1: Int) -> String { + return L10n.tr("Localizable", "menu.expiration.days", p1, fallback: "%d days") } - internal enum Open { - /// Open WiFi - internal static let wifi = L10n.tr("Localizable", "network.management.tool.open.wifi") + /// Subscription expires in + internal static let expiresIn = L10n.tr("Localizable", "menu.expiration.expires_in", fallback: "Subscription expires in") + /// %d hours + internal static func hours(_ p1: Int) -> String { + return L10n.tr("Localizable", "menu.expiration.hours", p1, fallback: "%d hours") } - internal enum Retain { - /// Retain VPN State - internal static let state = L10n.tr("Localizable", "network.management.tool.retain.state") + /// one hour + internal static let oneHour = L10n.tr("Localizable", "menu.expiration.one_hour", fallback: "one hour") + /// UPGRADE ACCOUNT + internal static let upgrade = L10n.tr("Localizable", "menu.expiration.upgrade", fallback: "UPGRADE ACCOUNT") + } + internal enum Item { + /// About + internal static let about = L10n.tr("Localizable", "menu.item.about", fallback: "About") + /// Account + internal static let account = L10n.tr("Localizable", "menu.item.account", fallback: "Account") + /// Log out + internal static let logout = L10n.tr("Localizable", "menu.item.logout", fallback: "Log out") + /// Region selection + internal static let region = L10n.tr("Localizable", "menu.item.region", fallback: "Region selection") + /// Settings + internal static let settings = L10n.tr("Localizable", "menu.item.settings", fallback: "Settings") + internal enum Web { + /// Home page + internal static let home = L10n.tr("Localizable", "menu.item.web.home", fallback: "Home page") + /// Privacy policy + internal static let privacy = L10n.tr("Localizable", "menu.item.web.privacy", fallback: "Privacy policy") + /// Support + internal static let support = L10n.tr("Localizable", "menu.item.web.support", fallback: "Support") } - internal enum Secure { - /// Secure WiFi - internal static let wifi = L10n.tr("Localizable", "network.management.tool.secure.wifi") + } + internal enum Logout { + /// Log out + internal static let confirm = L10n.tr("Localizable", "menu.logout.confirm", fallback: "Log out") + /// Logging out will disable the VPN and leave you unprotected. + internal static let message = L10n.tr("Localizable", "menu.logout.message", fallback: "Logging out will disable the VPN and leave you unprotected.") + /// Log out + internal static let title = L10n.tr("Localizable", "menu.logout.title", fallback: "Log out") + } + internal enum Renewal { + /// Purchase + internal static let purchase = L10n.tr("Localizable", "menu.renewal.purchase", fallback: "Purchase") + /// Renew + internal static let renew = L10n.tr("Localizable", "menu.renewal.renew", fallback: "Renew") + /// Renewal + internal static let title = L10n.tr("Localizable", "menu.renewal.title", fallback: "Renewal") + internal enum Message { + /// Trial accounts are not eligible for renewal. Please purchase a new account upon expiry to continue service. + internal static let trial = L10n.tr("Localizable", "menu.renewal.message.trial", fallback: "Trial accounts are not eligible for renewal. Please purchase a new account upon expiry to continue service.") + /// Apple servers currently unavailable. Please try again later. + internal static let unavailable = L10n.tr("Localizable", "menu.renewal.message.unavailable", fallback: "Apple servers currently unavailable. Please try again later.") + /// Please use our website to renew your subscription. + internal static let website = L10n.tr("Localizable", "menu.renewal.message.website", fallback: "Please use our website to renew your subscription.") } } } - } - - internal enum Notifications { - internal enum Disabled { - /// Enable notifications to get a reminder to renew your subscription before it expires. - internal static let message = L10n.tr("Localizable", "notifications.disabled.message") - /// Settings - internal static let settings = L10n.tr("Localizable", "notifications.disabled.settings") - /// Notifications disabled - internal static let title = L10n.tr("Localizable", "notifications.disabled.title") - } - } - - internal enum Rating { - internal enum Enjoy { - /// Are you enjoying PIA VPN? - internal static let question = L10n.tr("Localizable", "rating.enjoy.question") - /// We hope our VPN product is meeting your expectations - internal static let subtitle = L10n.tr("Localizable", "rating.enjoy.subtitle") - } - internal enum Error { - /// The connection couldn't be established - internal static let question = L10n.tr("Localizable", "rating.error.question") - /// You can try selecting a different region or letting us know about it by opening a support ticket. - internal static let subtitle = L10n.tr("Localizable", "rating.error.subtitle") - internal enum Button { - /// Send feedback - internal static let send = L10n.tr("Localizable", "rating.error.button.send") + internal enum Network { + internal enum Management { + internal enum Tool { + /// Your automation settings are configured to keep the VPN disconnected under the current network conditions. + internal static let alert = L10n.tr("Localizable", "network.management.tool.alert", fallback: "Your automation settings are configured to keep the VPN disconnected under the current network conditions.") + /// Disable Automation + internal static let disable = L10n.tr("Localizable", "network.management.tool.disable", fallback: "Disable Automation") + /// Manage Automation + internal static let title = L10n.tr("Localizable", "network.management.tool.title", fallback: "Manage Automation") + internal enum Add { + /// Add new rule + internal static let rule = L10n.tr("Localizable", "network.management.tool.add.rule", fallback: "Add new rule") + } + internal enum Always { + /// Always connect VPN + internal static let connect = L10n.tr("Localizable", "network.management.tool.always.connect", fallback: "Always connect VPN") + /// Always disconnect VPN + internal static let disconnect = L10n.tr("Localizable", "network.management.tool.always.disconnect", fallback: "Always disconnect VPN") + } + internal enum Choose { + /// Choose a WiFi network to add a new rule. + internal static let wifi = L10n.tr("Localizable", "network.management.tool.choose.wifi", fallback: "Choose a WiFi network to add a new rule. ") + } + internal enum Enable { + /// Enable Automation + internal static let automation = L10n.tr("Localizable", "network.management.tool.enable.automation", fallback: "Enable Automation") + } + internal enum Mobile { + /// Mobile data + internal static let data = L10n.tr("Localizable", "network.management.tool.mobile.data", fallback: "Mobile data") + } + internal enum Open { + /// Open WiFi + internal static let wifi = L10n.tr("Localizable", "network.management.tool.open.wifi", fallback: "Open WiFi") + } + internal enum Retain { + /// Retain VPN State + internal static let state = L10n.tr("Localizable", "network.management.tool.retain.state", fallback: "Retain VPN State") + } + internal enum Secure { + /// Secure WiFi + internal static let wifi = L10n.tr("Localizable", "network.management.tool.secure.wifi", fallback: "Secure WiFi") + } + } } } - internal enum Problems { - /// What went wrong? - internal static let question = L10n.tr("Localizable", "rating.problems.question") - /// Do you want to give feedback? We can help you to improve your experience using PIA - internal static let subtitle = L10n.tr("Localizable", "rating.problems.subtitle") - } - internal enum Rate { - /// How about an AppStore review? - internal static let question = L10n.tr("Localizable", "rating.rate.question") - /// We appreciate you sharing your experience - internal static let subtitle = L10n.tr("Localizable", "rating.rate.subtitle") - } - } - - internal enum Region { - internal enum Accessibility { - /// Add a favorite region - internal static let favorite = L10n.tr("Localizable", "region.accessibility.favorite") - /// Filter - internal static let filter = L10n.tr("Localizable", "region.accessibility.filter") - /// Remove a favorite region - internal static let unfavorite = L10n.tr("Localizable", "region.accessibility.unfavorite") - } - internal enum Filter { - /// Favorites - internal static let favorites = L10n.tr("Localizable", "region.filter.favorites") - /// Latency - internal static let latency = L10n.tr("Localizable", "region.filter.latency") - /// Name - internal static let name = L10n.tr("Localizable", "region.filter.name") - /// Sort regions by - internal static let sortby = L10n.tr("Localizable", "region.filter.sortby") - } - internal enum Search { - /// Search for a region - internal static let placeholder = L10n.tr("Localizable", "region.search.placeholder") - } - } - - internal enum Renewal { - internal enum Failure { - /// Your purchase receipt couldn't be submitted, please retry at a later time. - internal static let message = L10n.tr("Localizable", "renewal.failure.message") - } - internal enum Success { - /// Your account was successfully renewed. - internal static let message = L10n.tr("Localizable", "renewal.success.message") - /// Thank you - internal static let title = L10n.tr("Localizable", "renewal.success.title") + internal enum Notifications { + internal enum Disabled { + /// Enable notifications to get a reminder to renew your subscription before it expires. + internal static let message = L10n.tr("Localizable", "notifications.disabled.message", fallback: "Enable notifications to get a reminder to renew your subscription before it expires.") + /// Settings + internal static let settings = L10n.tr("Localizable", "notifications.disabled.settings", fallback: "Settings") + /// Notifications disabled + internal static let title = L10n.tr("Localizable", "notifications.disabled.title", fallback: "Notifications disabled") + } } - } - - internal enum Server { - internal enum Reconnection { - internal enum Please { - /// Please wait... - internal static let wait = L10n.tr("Localizable", "server.reconnection.please.wait") + internal enum Rating { + internal enum Alert { + internal enum Button { + /// No, thanks. + internal static let nothanks = L10n.tr("Localizable", "rating.alert.button.nothanks", fallback: "No, thanks.") + /// Not Really + internal static let notreally = L10n.tr("Localizable", "rating.alert.button.notreally", fallback: "Not Really") + /// Ok, sure! + internal static let oksure = L10n.tr("Localizable", "rating.alert.button.oksure", fallback: "Ok, sure!") + } } - internal enum Still { - /// Still trying to connect... - internal static let connection = L10n.tr("Localizable", "server.reconnection.still.connection") + internal enum Enjoy { + /// Are you enjoying PIA VPN? + internal static let question = L10n.tr("Localizable", "rating.enjoy.question", fallback: "Are you enjoying PIA VPN?") + /// We hope our VPN product is meeting your expectations + internal static let subtitle = L10n.tr("Localizable", "rating.enjoy.subtitle", fallback: "We hope our VPN product is meeting your expectations") } - } - } - - internal enum Set { - internal enum Email { - /// We need your email to send your username and password. - internal static let why = L10n.tr("Localizable", "set.email.why") internal enum Error { - /// You must enter an email address. - internal static let validation = L10n.tr("Localizable", "set.email.error.validation") + /// The connection couldn't be established + internal static let question = L10n.tr("Localizable", "rating.error.question", fallback: "The connection couldn't be established") + /// You can try selecting a different region or letting us know about it by opening a support ticket. + internal static let subtitle = L10n.tr("Localizable", "rating.error.subtitle", fallback: "You can try selecting a different region or letting us know about it by opening a support ticket.") + internal enum Button { + /// Send feedback + internal static let send = L10n.tr("Localizable", "rating.error.button.send", fallback: "Send feedback") + } } - internal enum Form { - /// Enter your email address - internal static let email = L10n.tr("Localizable", "set.email.form.email") + internal enum Problems { + /// What went wrong? + internal static let question = L10n.tr("Localizable", "rating.problems.question", fallback: "What went wrong?") + /// Do you want to give feedback? We can help you to improve your experience using PIA + internal static let subtitle = L10n.tr("Localizable", "rating.problems.subtitle", fallback: "Do you want to give feedback? We can help you to improve your experience using PIA") } - internal enum Password { - /// Password - internal static let caption = L10n.tr("Localizable", "set.email.password.caption") + internal enum Rate { + /// How about a rating on the AppStore? + internal static let question = L10n.tr("Localizable", "rating.rate.question", fallback: "How about a rating on the AppStore?") + /// We appreciate you sharing your experience + internal static let subtitle = L10n.tr("Localizable", "rating.rate.subtitle", fallback: "We appreciate you sharing your experience") + } + internal enum Review { + /// How about an AppStore review? + internal static let question = L10n.tr("Localizable", "rating.review.question", fallback: "How about an AppStore review?") + } + } + internal enum Region { + internal enum Accessibility { + /// Add a favorite region + internal static let favorite = L10n.tr("Localizable", "region.accessibility.favorite", fallback: "Add a favorite region") + /// Filter + internal static let filter = L10n.tr("Localizable", "region.accessibility.filter", fallback: "Filter") + /// Remove a favorite region + internal static let unfavorite = L10n.tr("Localizable", "region.accessibility.unfavorite", fallback: "Remove a favorite region") + } + internal enum Filter { + /// Favorites + internal static let favorites = L10n.tr("Localizable", "region.filter.favorites", fallback: "Favorites") + /// Latency + internal static let latency = L10n.tr("Localizable", "region.filter.latency", fallback: "Latency") + /// Name + internal static let name = L10n.tr("Localizable", "region.filter.name", fallback: "Name") + /// Sort regions by + internal static let sortby = L10n.tr("Localizable", "region.filter.sortby", fallback: "Sort regions by") + } + internal enum Search { + /// Search for a region + internal static let placeholder = L10n.tr("Localizable", "region.search.placeholder", fallback: "Search for a region") + } + } + internal enum Renewal { + internal enum Failure { + /// Your purchase receipt couldn't be submitted, please retry at a later time. + internal static let message = L10n.tr("Localizable", "renewal.failure.message", fallback: "Your purchase receipt couldn't be submitted, please retry at a later time.") } internal enum Success { - /// We have sent your account username and password at your email address at %@ - internal static func messageFormat(_ p1: Any) -> String { - return L10n.tr("Localizable", "set.email.success.message_format", String(describing: p1)) + /// Your account was successfully renewed. + internal static let message = L10n.tr("Localizable", "renewal.success.message", fallback: "Your account was successfully renewed.") + /// Thank you + internal static let title = L10n.tr("Localizable", "renewal.success.title", fallback: "Thank you") + } + } + internal enum Server { + internal enum Reconnection { + internal enum Please { + /// Please wait... + internal static let wait = L10n.tr("Localizable", "server.reconnection.please.wait", fallback: "Please wait...") + } + internal enum Still { + /// Still trying to connect... + internal static let connection = L10n.tr("Localizable", "server.reconnection.still.connection", fallback: "Still trying to connect...") } } } - } - - internal enum Settings { - internal enum ApplicationInformation { - /// APPLICATION INFORMATION - internal static let title = L10n.tr("Localizable", "settings.application_information.title") - internal enum Debug { - /// Send Debug Log to support - internal static let title = L10n.tr("Localizable", "settings.application_information.debug.title") - internal enum Empty { - /// Debug information is empty, please attempt a connection before retrying submission. - internal static let message = L10n.tr("Localizable", "settings.application_information.debug.empty.message") - /// Empty debug information - internal static let title = L10n.tr("Localizable", "settings.application_information.debug.empty.title") + internal enum Set { + internal enum Email { + /// We need your email to send your username and password. + internal static let why = L10n.tr("Localizable", "set.email.why", fallback: "We need your email to send your username and password.") + internal enum Error { + /// You must enter an email address. + internal static let validation = L10n.tr("Localizable", "set.email.error.validation", fallback: "You must enter an email address.") } - internal enum Failure { - /// Debug information could not be submitted. - internal static let message = L10n.tr("Localizable", "settings.application_information.debug.failure.message") - /// Error during submission - internal static let title = L10n.tr("Localizable", "settings.application_information.debug.failure.title") + internal enum Form { + /// Enter your email address + internal static let email = L10n.tr("Localizable", "set.email.form.email", fallback: "Enter your email address") + } + internal enum Password { + /// Password + internal static let caption = L10n.tr("Localizable", "set.email.password.caption", fallback: "Password") } internal enum Success { - /// Debug information successfully submitted.\nID: %@\nPlease note this ID, as our support team will require this to locate your submission. - internal static func message(_ p1: Any) -> String { - return L10n.tr("Localizable", "settings.application_information.debug.success.message", String(describing: p1)) + /// We have sent your account username and password at your email address at %@ + internal static func messageFormat(_ p1: Any) -> String { + return L10n.tr("Localizable", "set.email.success.message_format", String(describing: p1), fallback: "We have sent your account username and password at your email address at %@") } - /// Debug information submitted - internal static let title = L10n.tr("Localizable", "settings.application_information.debug.success.title") } } } - internal enum ApplicationSettings { - /// APPLICATION SETTINGS - internal static let title = L10n.tr("Localizable", "settings.application_settings.title") - internal enum ActiveTheme { - /// Active theme - internal static let title = L10n.tr("Localizable", "settings.application_settings.active_theme.title") - } - internal enum DarkTheme { - /// Dark theme - internal static let title = L10n.tr("Localizable", "settings.application_settings.dark_theme.title") - } - internal enum KillSwitch { - /// The VPN kill switch prevents access to the Internet if the VPN connection is reconnecting. This excludes disconnecting manually. - internal static let footer = L10n.tr("Localizable", "settings.application_settings.kill_switch.footer") - /// VPN Kill Switch - internal static let title = L10n.tr("Localizable", "settings.application_settings.kill_switch.title") - } - internal enum Mace { - /// PIA MACE™ blocks ads, trackers, and malware while you're connected to the VPN. - internal static let footer = L10n.tr("Localizable", "settings.application_settings.mace.footer") - /// PIA MACE™ - internal static let title = L10n.tr("Localizable", "settings.application_settings.mace.title") + internal enum Settings { + internal enum ApplicationInformation { + /// APPLICATION INFORMATION + internal static let title = L10n.tr("Localizable", "settings.application_information.title", fallback: "APPLICATION INFORMATION") + internal enum Debug { + /// Send Debug Log to support + internal static let title = L10n.tr("Localizable", "settings.application_information.debug.title", fallback: "Send Debug Log to support") + internal enum Empty { + /// Debug information is empty, please attempt a connection before retrying submission. + internal static let message = L10n.tr("Localizable", "settings.application_information.debug.empty.message", fallback: "Debug information is empty, please attempt a connection before retrying submission.") + /// Empty debug information + internal static let title = L10n.tr("Localizable", "settings.application_information.debug.empty.title", fallback: "Empty debug information") + } + internal enum Failure { + /// Debug information could not be submitted. + internal static let message = L10n.tr("Localizable", "settings.application_information.debug.failure.message", fallback: "Debug information could not be submitted.") + /// Error during submission + internal static let title = L10n.tr("Localizable", "settings.application_information.debug.failure.title", fallback: "Error during submission") + } + internal enum Success { + /// Debug information successfully submitted. + /// ID: %@ + /// Please note this ID, as our support team will require this to locate your submission. + internal static func message(_ p1: Any) -> String { + return L10n.tr("Localizable", "settings.application_information.debug.success.message", String(describing: p1), fallback: "Debug information successfully submitted.\nID: %@\nPlease note this ID, as our support team will require this to locate your submission.") + } + /// Debug information submitted + internal static let title = L10n.tr("Localizable", "settings.application_information.debug.success.title", fallback: "Debug information submitted") + } + } } - } - internal enum Cards { - internal enum History { - /// Latest News - internal static let title = L10n.tr("Localizable", "settings.cards.history.title") + internal enum ApplicationSettings { + /// APPLICATION SETTINGS + internal static let title = L10n.tr("Localizable", "settings.application_settings.title", fallback: "APPLICATION SETTINGS") + internal enum ActiveTheme { + /// Active theme + internal static let title = L10n.tr("Localizable", "settings.application_settings.active_theme.title", fallback: "Active theme") + } + internal enum AllowLocalNetwork { + /// Stay connected to local devices like printers or file servers while connected to the VPN. (Allow this only if you trust the people and devices on your network.) + internal static let footer = L10n.tr("Localizable", "settings.application_settings.allow_local_network.footer", fallback: "Stay connected to local devices like printers or file servers while connected to the VPN. (Allow this only if you trust the people and devices on your network.)") + /// Allow access to devices on local network + internal static let title = L10n.tr("Localizable", "settings.application_settings.allow_local_network.title", fallback: "Allow access to devices on local network") + } + internal enum DarkTheme { + /// Dark theme + internal static let title = L10n.tr("Localizable", "settings.application_settings.dark_theme.title", fallback: "Dark theme") + } + internal enum KillSwitch { + /// The VPN kill switch prevents access to the Internet if the VPN connection is reconnecting. This excludes disconnecting manually. + internal static let footer = L10n.tr("Localizable", "settings.application_settings.kill_switch.footer", fallback: "The VPN kill switch prevents access to the Internet if the VPN connection is reconnecting. This excludes disconnecting manually.") + /// VPN Kill Switch + internal static let title = L10n.tr("Localizable", "settings.application_settings.kill_switch.title", fallback: "VPN Kill Switch") + } + internal enum LeakProtection { + /// iOS includes features designed to operate outside the VPN by default, such as AirDrop, CarPlay, AirPlay, and Personal Hotspots. Enabling custom leak protection routes this traffic through the VPN but may affect how these features function. More info + internal static let footer = L10n.tr("Localizable", "settings.application_settings.leak_protection.footer", fallback: "iOS includes features designed to operate outside the VPN by default, such as AirDrop, CarPlay, AirPlay, and Personal Hotspots. Enabling custom leak protection routes this traffic through the VPN but may affect how these features function. More info") + /// More info + internal static let moreInfo = L10n.tr("Localizable", "settings.application_settings.leak_protection.more_info", fallback: "More info") + /// Leak Protection + internal static let title = L10n.tr("Localizable", "settings.application_settings.leak_protection.title", fallback: "Leak Protection") + internal enum Alert { + /// Changes to the VPN Settings will take effect on the next connection + internal static let title = L10n.tr("Localizable", "settings.application_settings.leak_protection.alert.title", fallback: "Changes to the VPN Settings will take effect on the next connection") + } + } + internal enum Mace { + /// PIA MACE™ blocks ads, trackers, and malware while you're connected to the VPN. + internal static let footer = L10n.tr("Localizable", "settings.application_settings.mace.footer", fallback: "PIA MACE™ blocks ads, trackers, and malware while you're connected to the VPN.") + /// PIA MACE™ + internal static let title = L10n.tr("Localizable", "settings.application_settings.mace.title", fallback: "PIA MACE™") + } } - } - internal enum Commit { - internal enum Buttons { - /// Later - internal static let later = L10n.tr("Localizable", "settings.commit.buttons.later") - /// Reconnect - internal static let reconnect = L10n.tr("Localizable", "settings.commit.buttons.reconnect") + internal enum Cards { + internal enum History { + /// Latest News + internal static let title = L10n.tr("Localizable", "settings.cards.history.title", fallback: "Latest News") + } } - internal enum Messages { - /// The VPN must reconnect for some changes to take effect. - internal static let mustDisconnect = L10n.tr("Localizable", "settings.commit.messages.must_disconnect") - /// Reconnect the VPN to apply changes. - internal static let shouldReconnect = L10n.tr("Localizable", "settings.commit.messages.should_reconnect") + internal enum Commit { + internal enum Buttons { + /// Later + internal static let later = L10n.tr("Localizable", "settings.commit.buttons.later", fallback: "Later") + /// Reconnect + internal static let reconnect = L10n.tr("Localizable", "settings.commit.buttons.reconnect", fallback: "Reconnect") + } + internal enum Messages { + /// The VPN must reconnect for some changes to take effect. + internal static let mustDisconnect = L10n.tr("Localizable", "settings.commit.messages.must_disconnect", fallback: "The VPN must reconnect for some changes to take effect.") + /// Reconnect the VPN to apply changes. + internal static let shouldReconnect = L10n.tr("Localizable", "settings.commit.messages.should_reconnect", fallback: "Reconnect the VPN to apply changes.") + } } - } - internal enum Connection { - /// CONNECTION - internal static let title = L10n.tr("Localizable", "settings.connection.title") - internal enum RemotePort { - /// Remote Port - internal static let title = L10n.tr("Localizable", "settings.connection.remote_port.title") + internal enum Connection { + /// CONNECTION + internal static let title = L10n.tr("Localizable", "settings.connection.title", fallback: "CONNECTION") + internal enum RemotePort { + /// Remote Port + internal static let title = L10n.tr("Localizable", "settings.connection.remote_port.title", fallback: "Remote Port") + } + internal enum SocketProtocol { + /// Socket + internal static let title = L10n.tr("Localizable", "settings.connection.socket_protocol.title", fallback: "Socket") + } + internal enum Transport { + /// Transport + internal static let title = L10n.tr("Localizable", "settings.connection.transport.title", fallback: "Transport") + } + internal enum VpnProtocol { + /// Protocol Selection + internal static let title = L10n.tr("Localizable", "settings.connection.vpn_protocol.title", fallback: "Protocol Selection") + } } - internal enum SocketProtocol { - /// Socket - internal static let title = L10n.tr("Localizable", "settings.connection.socket_protocol.title") + internal enum ContentBlocker { + /// To enable or disable Content Blocker go to Settings > Safari > Content Blockers and toggle PIA VPN. + internal static let footer = L10n.tr("Localizable", "settings.content_blocker.footer", fallback: "To enable or disable Content Blocker go to Settings > Safari > Content Blockers and toggle PIA VPN.") + /// Safari Content Blocker state + internal static let title = L10n.tr("Localizable", "settings.content_blocker.title", fallback: "Safari Content Blocker state") + internal enum Refresh { + /// Refresh block list + internal static let title = L10n.tr("Localizable", "settings.content_blocker.refresh.title", fallback: "Refresh block list") + } + internal enum State { + /// Current state + internal static let title = L10n.tr("Localizable", "settings.content_blocker.state.title", fallback: "Current state") + } } - internal enum Transport { - /// Transport - internal static let title = L10n.tr("Localizable", "settings.connection.transport.title") + internal enum Dns { + /// Custom + internal static let custom = L10n.tr("Localizable", "settings.dns.custom", fallback: "Custom") + /// Primary DNS + internal static let primaryDNS = L10n.tr("Localizable", "settings.dns.primaryDNS", fallback: "Primary DNS") + /// Secondary DNS + internal static let secondaryDNS = L10n.tr("Localizable", "settings.dns.secondaryDNS", fallback: "Secondary DNS") + internal enum Alert { + internal enum Clear { + /// This will clear your custom DNS and default to PIA DNS. + internal static let message = L10n.tr("Localizable", "settings.dns.alert.clear.message", fallback: "This will clear your custom DNS and default to PIA DNS.") + /// Clear DNS + internal static let title = L10n.tr("Localizable", "settings.dns.alert.clear.title", fallback: "Clear DNS") + } + internal enum Create { + /// Using non PIA DNS could expose your DNS traffic to third parties and compromise your privacy. + internal static let message = L10n.tr("Localizable", "settings.dns.alert.create.message", fallback: "Using non PIA DNS could expose your DNS traffic to third parties and compromise your privacy.") + } + } + internal enum Custom { + /// Custom DNS + internal static let dns = L10n.tr("Localizable", "settings.dns.custom.dns", fallback: "Custom DNS") + } + internal enum Validation { + internal enum Primary { + /// Primary DNS is not valid. + internal static let invalid = L10n.tr("Localizable", "settings.dns.validation.primary.invalid", fallback: "Primary DNS is not valid.") + /// Primary DNS is mandatory. + internal static let mandatory = L10n.tr("Localizable", "settings.dns.validation.primary.mandatory", fallback: "Primary DNS is mandatory.") + } + internal enum Secondary { + /// Secondary DNS is not valid. + internal static let invalid = L10n.tr("Localizable", "settings.dns.validation.secondary.invalid", fallback: "Secondary DNS is not valid.") + } + } } - internal enum VpnProtocol { - /// Protocol Selection - internal static let title = L10n.tr("Localizable", "settings.connection.vpn_protocol.title") + internal enum Encryption { + /// ENCRYPTION + internal static let title = L10n.tr("Localizable", "settings.encryption.title", fallback: "ENCRYPTION") + internal enum Cipher { + /// Data Encryption + internal static let title = L10n.tr("Localizable", "settings.encryption.cipher.title", fallback: "Data Encryption") + } + internal enum Digest { + /// Data Authentication + internal static let title = L10n.tr("Localizable", "settings.encryption.digest.title", fallback: "Data Authentication") + } + internal enum Handshake { + /// Handshake + internal static let title = L10n.tr("Localizable", "settings.encryption.handshake.title", fallback: "Handshake") + } } - } - internal enum ContentBlocker { - /// To enable or disable Content Blocker go to Settings > Safari > Content Blockers and toggle PIA VPN. - internal static let footer = L10n.tr("Localizable", "settings.content_blocker.footer") - /// Safari Content Blocker state - internal static let title = L10n.tr("Localizable", "settings.content_blocker.title") - internal enum Refresh { - /// Refresh block list - internal static let title = L10n.tr("Localizable", "settings.content_blocker.refresh.title") - } - internal enum State { - /// Current state - internal static let title = L10n.tr("Localizable", "settings.content_blocker.state.title") + internal enum Geo { + internal enum Servers { + /// Show Geo-located Regions + internal static let description = L10n.tr("Localizable", "settings.geo.servers.description", fallback: "Show Geo-located Regions") + } } - } - internal enum Dns { - /// Custom - internal static let custom = L10n.tr("Localizable", "settings.dns.custom") - /// Primary DNS - internal static let primaryDNS = L10n.tr("Localizable", "settings.dns.primaryDNS") - /// Secondary DNS - internal static let secondaryDNS = L10n.tr("Localizable", "settings.dns.secondaryDNS") - internal enum Alert { - internal enum Clear { - /// This will clear your custom DNS and default to PIA DNS. - internal static let message = L10n.tr("Localizable", "settings.dns.alert.clear.message") - /// Clear DNS - internal static let title = L10n.tr("Localizable", "settings.dns.alert.clear.title") + internal enum Hotspothelper { + /// Configure how PIA will behaves on connection to WiFi or cellular networks. This excludes disconnecting manually. + internal static let description = L10n.tr("Localizable", "settings.hotspothelper.description", fallback: "Configure how PIA will behaves on connection to WiFi or cellular networks. This excludes disconnecting manually.") + /// Network management tool + internal static let title = L10n.tr("Localizable", "settings.hotspothelper.title", fallback: "Network management tool") + internal enum All { + /// VPN WiFi Protection will activate on all networks, including trusted networks. + internal static let description = L10n.tr("Localizable", "settings.hotspothelper.all.description", fallback: "VPN WiFi Protection will activate on all networks, including trusted networks.") + /// Protect all networks + internal static let title = L10n.tr("Localizable", "settings.hotspothelper.all.title", fallback: "Protect all networks") + } + internal enum Available { + /// To populate this list go to iOS Settings > WiFi. + internal static let help = L10n.tr("Localizable", "settings.hotspothelper.available.help", fallback: "To populate this list go to iOS Settings > WiFi.") + internal enum Add { + /// Tap + to add to Trusted networks. + internal static let help = L10n.tr("Localizable", "settings.hotspothelper.available.add.help", fallback: "Tap + to add to Trusted networks.") + } } - internal enum Create { - /// Using non PIA DNS could expose your DNS traffic to third parties and compromise your privacy. - internal static let message = L10n.tr("Localizable", "settings.dns.alert.create.message") + internal enum Cellular { + /// PIA automatically enables the VPN when connecting to cellular networks if this option is enabled. + internal static let description = L10n.tr("Localizable", "settings.hotspothelper.cellular.description", fallback: "PIA automatically enables the VPN when connecting to cellular networks if this option is enabled.") + /// Cellular networks + internal static let networks = L10n.tr("Localizable", "settings.hotspothelper.cellular.networks", fallback: "Cellular networks") + /// Protect over cellular networks + internal static let title = L10n.tr("Localizable", "settings.hotspothelper.cellular.title", fallback: "Protect over cellular networks") + } + internal enum Enable { + /// PIA automatically enables the VPN when connecting to untrusted WiFi networks if this option is enabled. + internal static let description = L10n.tr("Localizable", "settings.hotspothelper.enable.description", fallback: "PIA automatically enables the VPN when connecting to untrusted WiFi networks if this option is enabled.") + } + internal enum Rules { + /// Rules + internal static let title = L10n.tr("Localizable", "settings.hotspothelper.rules.title", fallback: "Rules") + } + internal enum Wifi { + /// WiFi networks + internal static let networks = L10n.tr("Localizable", "settings.hotspothelper.wifi.networks", fallback: "WiFi networks") + internal enum Trust { + /// VPN WiFi Protection + internal static let title = L10n.tr("Localizable", "settings.hotspothelper.wifi.trust.title", fallback: "VPN WiFi Protection") + } } } - internal enum Custom { - /// Custom DNS - internal static let dns = L10n.tr("Localizable", "settings.dns.custom.dns") + internal enum Log { + /// Save debug logs which can be submitted to technical support to help troubleshoot problems. + internal static let information = L10n.tr("Localizable", "settings.log.information", fallback: "Save debug logs which can be submitted to technical support to help troubleshoot problems.") + internal enum Connected { + /// A VPN connection is required. Please connect to the VPN and retry. + internal static let error = L10n.tr("Localizable", "settings.log.connected.error", fallback: "A VPN connection is required. Please connect to the VPN and retry.") + } } - internal enum Validation { - internal enum Primary { - /// Primary DNS is not valid. - internal static let invalid = L10n.tr("Localizable", "settings.dns.validation.primary.invalid") - /// Primary DNS is mandatory. - internal static let mandatory = L10n.tr("Localizable", "settings.dns.validation.primary.mandatory") + internal enum Nmt { + internal enum Killswitch { + /// The VPN kill switch is currently disabled. In order to ensure that the Network Management Tool is functioning, and that you are able to reconnect when switching networks, please enable the VPN kill switch in your settings. + internal static let disabled = L10n.tr("Localizable", "settings.nmt.killswitch.disabled", fallback: "The VPN kill switch is currently disabled. In order to ensure that the Network Management Tool is functioning, and that you are able to reconnect when switching networks, please enable the VPN kill switch in your settings.") } - internal enum Secondary { - /// Secondary DNS is not valid. - internal static let invalid = L10n.tr("Localizable", "settings.dns.validation.secondary.invalid") + internal enum Optout { + internal enum Disconnect { + /// Opt-out disconnect confirmation alert + internal static let alerts = L10n.tr("Localizable", "settings.nmt.optout.disconnect.alerts", fallback: "Opt-out disconnect confirmation alert") + internal enum Alerts { + /// Disables the warning alert when disconnecting from the VPN. + internal static let description = L10n.tr("Localizable", "settings.nmt.optout.disconnect.alerts.description", fallback: "Disables the warning alert when disconnecting from the VPN.") + } + } + } + internal enum Wireguard { + /// WireGuard® doesn't need to reconnect when you switch between different networks. It may be necessary to manually disconnect the VPN on trusted networks. + internal static let warning = L10n.tr("Localizable", "settings.nmt.wireguard.warning", fallback: "WireGuard® doesn't need to reconnect when you switch between different networks. It may be necessary to manually disconnect the VPN on trusted networks.") } } - } - internal enum Encryption { - /// ENCRYPTION - internal static let title = L10n.tr("Localizable", "settings.encryption.title") - internal enum Cipher { - /// Data Encryption - internal static let title = L10n.tr("Localizable", "settings.encryption.cipher.title") + internal enum Ovpn { + internal enum Migration { + /// We are updating our OpenVPN implementation, for more information, click here + internal static let footer = L10n.tr("Localizable", "settings.ovpn.migration.footer", fallback: "We are updating our OpenVPN implementation, for more information, click here") + internal enum Footer { + /// here + internal static let link = L10n.tr("Localizable", "settings.ovpn.migration.footer.link", fallback: "here") + } + } } - internal enum Digest { - /// Data Authentication - internal static let title = L10n.tr("Localizable", "settings.encryption.digest.title") + internal enum Preview { + /// Preview + internal static let title = L10n.tr("Localizable", "settings.preview.title", fallback: "Preview") + } + internal enum Reset { + /// This will reset all of the above settings to default. + internal static let footer = L10n.tr("Localizable", "settings.reset.footer", fallback: "This will reset all of the above settings to default.") + /// RESET + internal static let title = L10n.tr("Localizable", "settings.reset.title", fallback: "RESET") + internal enum Defaults { + /// Reset settings to default + internal static let title = L10n.tr("Localizable", "settings.reset.defaults.title", fallback: "Reset settings to default") + internal enum Confirm { + /// Reset + internal static let button = L10n.tr("Localizable", "settings.reset.defaults.confirm.button", fallback: "Reset") + /// This will bring the app back to default. You will lose all changes you have made. + internal static let message = L10n.tr("Localizable", "settings.reset.defaults.confirm.message", fallback: "This will bring the app back to default. You will lose all changes you have made.") + /// Reset settings + internal static let title = L10n.tr("Localizable", "settings.reset.defaults.confirm.title", fallback: "Reset settings") + } + } } - internal enum Handshake { - /// Handshake - internal static let title = L10n.tr("Localizable", "settings.encryption.handshake.title") + internal enum Section { + /// Automation + internal static let automation = L10n.tr("Localizable", "settings.section.automation", fallback: "Automation") + /// General + internal static let general = L10n.tr("Localizable", "settings.section.general", fallback: "General") + /// Help + internal static let help = L10n.tr("Localizable", "settings.section.help", fallback: "Help") + /// Network + internal static let network = L10n.tr("Localizable", "settings.section.network", fallback: "Network") + /// Privacy Features + internal static let privacyFeatures = L10n.tr("Localizable", "settings.section.privacyFeatures", fallback: "Privacy Features") + /// Protocols + internal static let protocols = L10n.tr("Localizable", "settings.section.protocols", fallback: "Protocols") + } + internal enum Server { + internal enum Network { + /// The VPN has to be disconnected to change the server network. + internal static let alert = L10n.tr("Localizable", "settings.server.network.alert", fallback: "The VPN has to be disconnected to change the server network.") + /// Next generation network + internal static let description = L10n.tr("Localizable", "settings.server.network.description", fallback: "Next generation network") + } } - } - internal enum Geo { - internal enum Servers { - /// Show Geo-located Regions - internal static let description = L10n.tr("Localizable", "settings.geo.servers.description") + internal enum Service { + internal enum Quality { + internal enum Share { + /// Help us improve by sharing VPN connection statistics. These reports never contain personally identifiable information. + internal static let description = L10n.tr("Localizable", "settings.service.quality.share.description", fallback: "Help us improve by sharing VPN connection statistics. These reports never contain personally identifiable information.") + /// Find out more + internal static let findoutmore = L10n.tr("Localizable", "settings.service.quality.share.findoutmore", fallback: "Find out more") + /// Help improve PIA + internal static let title = L10n.tr("Localizable", "settings.service.quality.share.title", fallback: "Help improve PIA") + } + internal enum Show { + /// Connection stats + internal static let title = L10n.tr("Localizable", "settings.service.quality.show.title", fallback: "Connection stats") + } + } + } + internal enum Small { + internal enum Packets { + /// Will slightly lower the IP packet size to improve compatibility with some routers and mobile networks. + internal static let description = L10n.tr("Localizable", "settings.small.packets.description", fallback: "Will slightly lower the IP packet size to improve compatibility with some routers and mobile networks.") + /// Use Small Packets + internal static let title = L10n.tr("Localizable", "settings.small.packets.title", fallback: "Use Small Packets") + } + } + internal enum Trusted { + internal enum Networks { + /// PIA won't automatically connect on these networks. + internal static let message = L10n.tr("Localizable", "settings.trusted.networks.message", fallback: "PIA won't automatically connect on these networks.") + internal enum Connect { + /// Protect this network by connecting to VPN? + internal static let message = L10n.tr("Localizable", "settings.trusted.networks.connect.message", fallback: "Protect this network by connecting to VPN?") + } + internal enum Sections { + /// Available networks + internal static let available = L10n.tr("Localizable", "settings.trusted.networks.sections.available", fallback: "Available networks") + /// Current network + internal static let current = L10n.tr("Localizable", "settings.trusted.networks.sections.current", fallback: "Current network") + /// Trusted networks + internal static let trusted = L10n.tr("Localizable", "settings.trusted.networks.sections.trusted", fallback: "Trusted networks") + /// Untrusted networks + internal static let untrusted = L10n.tr("Localizable", "settings.trusted.networks.sections.untrusted", fallback: "Untrusted networks") + internal enum Trusted { + internal enum Rule { + /// Disconnect from PIA VPN + internal static let action = L10n.tr("Localizable", "settings.trusted.networks.sections.trusted.rule.action", fallback: "Disconnect from PIA VPN") + /// Enable this feature, with the VPN kill switch enabled, to customize how PIA will behave on WiFi and cellular networks. Please be aware, functionality of the Network Management Tool will be disabled if you manually disconnect. + internal static let description = L10n.tr("Localizable", "settings.trusted.networks.sections.trusted.rule.description", fallback: "Enable this feature, with the VPN kill switch enabled, to customize how PIA will behave on WiFi and cellular networks. Please be aware, functionality of the Network Management Tool will be disabled if you manually disconnect.") + } + } + } + } } } - internal enum Hotspothelper { - /// Configure how PIA will behaves on connection to WiFi or cellular networks. This excludes disconnecting manually. - internal static let description = L10n.tr("Localizable", "settings.hotspothelper.description") - /// Network management tool - internal static let title = L10n.tr("Localizable", "settings.hotspothelper.title") - internal enum All { - /// VPN WiFi Protection will activate on all networks, including trusted networks. - internal static let description = L10n.tr("Localizable", "settings.hotspothelper.all.description") - /// Protect all networks - internal static let title = L10n.tr("Localizable", "settings.hotspothelper.all.title") - } - internal enum Available { - /// To populate this list go to iOS Settings > WiFi. - internal static let help = L10n.tr("Localizable", "settings.hotspothelper.available.help") + internal enum Shortcuts { + /// Connect + internal static let connect = L10n.tr("Localizable", "shortcuts.connect", fallback: "Connect") + /// Disconnect + internal static let disconnect = L10n.tr("Localizable", "shortcuts.disconnect", fallback: "Disconnect") + /// Select a region + internal static let selectRegion = L10n.tr("Localizable", "shortcuts.select_region", fallback: "Select a region") + } + internal enum Siri { + internal enum Shortcuts { internal enum Add { - /// Tap + to add to Trusted networks. - internal static let help = L10n.tr("Localizable", "settings.hotspothelper.available.add.help") + /// There was an error adding the Siri shortcut. Please, try it again. + internal static let error = L10n.tr("Localizable", "siri.shortcuts.add.error", fallback: "There was an error adding the Siri shortcut. Please, try it again.") + } + internal enum Connect { + /// Connect PIA VPN + internal static let title = L10n.tr("Localizable", "siri.shortcuts.connect.title", fallback: "Connect PIA VPN") + internal enum Row { + /// 'Connect' Siri Shortcut + internal static let title = L10n.tr("Localizable", "siri.shortcuts.connect.row.title", fallback: "'Connect' Siri Shortcut") + } + } + internal enum Disconnect { + /// Disconnect PIA VPN + internal static let title = L10n.tr("Localizable", "siri.shortcuts.disconnect.title", fallback: "Disconnect PIA VPN") + internal enum Row { + /// 'Disconnect' Siri Shortcut + internal static let title = L10n.tr("Localizable", "siri.shortcuts.disconnect.row.title", fallback: "'Disconnect' Siri Shortcut") + } } } - internal enum Cellular { - /// PIA automatically enables the VPN when connecting to cellular networks if this option is enabled. - internal static let description = L10n.tr("Localizable", "settings.hotspothelper.cellular.description") - /// Cellular networks - internal static let networks = L10n.tr("Localizable", "settings.hotspothelper.cellular.networks") - /// Protect over cellular networks - internal static let title = L10n.tr("Localizable", "settings.hotspothelper.cellular.title") - } - internal enum Enable { - /// PIA automatically enables the VPN when connecting to untrusted WiFi networks if this option is enabled. - internal static let description = L10n.tr("Localizable", "settings.hotspothelper.enable.description") + } + internal enum Tiles { + internal enum Accessibility { + internal enum Invisible { + internal enum Tile { + /// Tap to add this tile to the dashboard + internal static let action = L10n.tr("Localizable", "tiles.accessibility.invisible.tile.action", fallback: "Tap to add this tile to the dashboard") + } + } + internal enum Visible { + internal enum Tile { + /// Tap to remove this tile from the dashboard + internal static let action = L10n.tr("Localizable", "tiles.accessibility.visible.tile.action", fallback: "Tap to remove this tile from the dashboard") + } + } } - internal enum Rules { - /// Rules - internal static let title = L10n.tr("Localizable", "settings.hotspothelper.rules.title") + internal enum Favorite { + internal enum Servers { + /// Favorite servers + internal static let title = L10n.tr("Localizable", "tiles.favorite.servers.title", fallback: "Favorite servers") + } } - internal enum Wifi { - /// WiFi networks - internal static let networks = L10n.tr("Localizable", "settings.hotspothelper.wifi.networks") - internal enum Trust { - /// VPN WiFi Protection - internal static let title = L10n.tr("Localizable", "settings.hotspothelper.wifi.trust.title") + internal enum Nmt { + /// Cellular + internal static let cellular = L10n.tr("Localizable", "tiles.nmt.cellular", fallback: "Cellular") + internal enum Accessibility { + /// Trusted network + internal static let trusted = L10n.tr("Localizable", "tiles.nmt.accessibility.trusted", fallback: "Trusted network") + /// Untrusted network + internal static let untrusted = L10n.tr("Localizable", "tiles.nmt.accessibility.untrusted", fallback: "Untrusted network") } } - } - internal enum Log { - /// Save debug logs which can be submitted to technical support to help troubleshoot problems. - internal static let information = L10n.tr("Localizable", "settings.log.information") - internal enum Connected { - /// A VPN connection is required. Please connect to the VPN and retry. - internal static let error = L10n.tr("Localizable", "settings.log.connected.error") + internal enum Quick { + internal enum Connect { + /// Quick connect + internal static let title = L10n.tr("Localizable", "tiles.quick.connect.title", fallback: "Quick connect") + } } - } - internal enum Nmt { - internal enum Killswitch { - /// The VPN kill switch is currently disabled. In order to ensure that the Network Management Tool is functioning, and that you are able to reconnect when switching networks, please enable the VPN kill switch in your settings. - internal static let disabled = L10n.tr("Localizable", "settings.nmt.killswitch.disabled") + internal enum Quicksetting { + internal enum Nmt { + /// Network Management + internal static let title = L10n.tr("Localizable", "tiles.quicksetting.nmt.title", fallback: "Network Management") + } + internal enum Private { + internal enum Browser { + /// Private Browser + internal static let title = L10n.tr("Localizable", "tiles.quicksetting.private.browser.title", fallback: "Private Browser") + } + } } - internal enum Optout { - internal enum Disconnect { - /// Opt-out disconnect confirmation alert - internal static let alerts = L10n.tr("Localizable", "settings.nmt.optout.disconnect.alerts") - internal enum Alerts { - /// Disables the warning alert when disconnecting from the VPN. - internal static let description = L10n.tr("Localizable", "settings.nmt.optout.disconnect.alerts.description") + internal enum Quicksettings { + /// Quick settings + internal static let title = L10n.tr("Localizable", "tiles.quicksettings.title", fallback: "Quick settings") + internal enum Min { + internal enum Elements { + /// You should keep at least one element visible in the Quick Settings Tile + internal static let message = L10n.tr("Localizable", "tiles.quicksettings.min.elements.message", fallback: "You should keep at least one element visible in the Quick Settings Tile") } } } - internal enum Wireguard { - /// WireGuard® doesn't need to reconnect when you switch between different networks. It may be necessary to manually disconnect the VPN on trusted networks. - internal static let warning = L10n.tr("Localizable", "settings.nmt.wireguard.warning") + internal enum Region { + /// VPN Server + internal static let title = L10n.tr("Localizable", "tiles.region.title", fallback: "VPN Server") + } + internal enum Subscription { + /// Monthly + internal static let monthly = L10n.tr("Localizable", "tiles.subscription.monthly", fallback: "Monthly") + /// Subscription + internal static let title = L10n.tr("Localizable", "tiles.subscription.title", fallback: "Subscription") + /// Trial + internal static let trial = L10n.tr("Localizable", "tiles.subscription.trial", fallback: "Trial") + /// Yearly + internal static let yearly = L10n.tr("Localizable", "tiles.subscription.yearly", fallback: "Yearly") + internal enum Days { + /// (%d days left) + internal static func `left`(_ p1: Int) -> String { + return L10n.tr("Localizable", "tiles.subscription.days.left", p1, fallback: "(%d days left)") + } + } } - } - internal enum Ovpn { - internal enum Migration { - /// We are updating our OpenVPN implementation, for more information, click here - internal static let footer = L10n.tr("Localizable", "settings.ovpn.migration.footer") - internal enum Footer { - /// here - internal static let link = L10n.tr("Localizable", "settings.ovpn.migration.footer.link") + internal enum Usage { + /// Download + internal static let download = L10n.tr("Localizable", "tiles.usage.download", fallback: "Download") + /// Usage + internal static let title = L10n.tr("Localizable", "tiles.usage.title", fallback: "Usage") + /// Upload + internal static let upload = L10n.tr("Localizable", "tiles.usage.upload", fallback: "Upload") + internal enum Ipsec { + /// USAGE (Not available on IKEv2) + internal static let title = L10n.tr("Localizable", "tiles.usage.ipsec.title", fallback: "USAGE (Not available on IKEv2)") } } } - internal enum Preview { - /// Preview - internal static let title = L10n.tr("Localizable", "settings.preview.title") + internal enum Today { + internal enum Widget { + /// Login + internal static let login = L10n.tr("Localizable", "today.widget.login", fallback: "Login") + } } - internal enum Reset { - /// This will reset all of the above settings to default. - internal static let footer = L10n.tr("Localizable", "settings.reset.footer") - /// RESET - internal static let title = L10n.tr("Localizable", "settings.reset.title") - internal enum Defaults { - /// Reset settings to default - internal static let title = L10n.tr("Localizable", "settings.reset.defaults.title") - internal enum Confirm { - /// Reset - internal static let button = L10n.tr("Localizable", "settings.reset.defaults.confirm.button") - /// This will bring the app back to default. You will lose all changes you have made. - internal static let message = L10n.tr("Localizable", "settings.reset.defaults.confirm.message") - /// Reset settings - internal static let title = L10n.tr("Localizable", "settings.reset.defaults.confirm.title") + internal enum VpnPermission { + /// PIA + internal static let title = L10n.tr("Localizable", "vpn_permission.title", fallback: "PIA") + internal enum Body { + /// We don’t monitor, filter or log any network activity. + internal static let footer = L10n.tr("Localizable", "vpn_permission.body.footer", fallback: "We don’t monitor, filter or log any network activity.") + /// You’ll see a prompt for PIA VPN and need to allow access to VPN configurations. + /// To proceed tap on “%@”. + internal static func subtitle(_ p1: Any) -> String { + return L10n.tr("Localizable", "vpn_permission.body.subtitle", String(describing: p1), fallback: "You’ll see a prompt for PIA VPN and need to allow access to VPN configurations.\nTo proceed tap on “%@”.") + } + /// PIA needs access to your VPN profiles to secure your traffic + internal static let title = L10n.tr("Localizable", "vpn_permission.body.title", fallback: "PIA needs access to your VPN profiles to secure your traffic") + } + internal enum Disallow { + /// Contact + internal static let contact = L10n.tr("Localizable", "vpn_permission.disallow.contact", fallback: "Contact") + internal enum Message { + /// We need this permission for the application to function. + internal static let basic = L10n.tr("Localizable", "vpn_permission.disallow.message.basic", fallback: "We need this permission for the application to function.") + /// You can also get in touch with customer support if you need assistance. + internal static let support = L10n.tr("Localizable", "vpn_permission.disallow.message.support", fallback: "You can also get in touch with customer support if you need assistance.") } } } - internal enum Section { - /// Automation - internal static let automation = L10n.tr("Localizable", "settings.section.automation") - /// General - internal static let general = L10n.tr("Localizable", "settings.section.general") - /// Help - internal static let help = L10n.tr("Localizable", "settings.section.help") - /// Network - internal static let network = L10n.tr("Localizable", "settings.section.network") - /// Privacy Features - internal static let privacyFeatures = L10n.tr("Localizable", "settings.section.privacyFeatures") - /// Protocols - internal static let protocols = L10n.tr("Localizable", "settings.section.protocols") - } - internal enum Server { - internal enum Network { - /// The VPN has to be disconnected to change the server network. - internal static let alert = L10n.tr("Localizable", "settings.server.network.alert") - /// Next generation network - internal static let description = L10n.tr("Localizable", "settings.server.network.description") + internal enum Widget { + internal enum LiveActivity { + internal enum SelectedProtocol { + /// Protocol + internal static let title = L10n.tr("Localizable", "widget.liveActivity.protocol.title", fallback: "Protocol") + } + internal enum Region { + /// Region + internal static let title = L10n.tr("Localizable", "widget.liveActivity.region.title", fallback: "Region") + } } } - internal enum Service { - internal enum Quality { - internal enum Share { - /// Help us improve by sharing VPN connection statistics. These reports never contain personally identifiable information. - internal static let description = L10n.tr("Localizable", "settings.service.quality.share.description") - /// Find out more - internal static let findoutmore = L10n.tr("Localizable", "settings.service.quality.share.findoutmore") - /// Help improve PIA - internal static let title = L10n.tr("Localizable", "settings.service.quality.share.title") + } + internal enum Signup { + internal enum Failure { + /// We're unable to create an account at this time. Please try again later. Reopening the app will re-attempt to create an account. + internal static let message = L10n.tr("Signup", "failure.message", fallback: "We're unable to create an account at this time. Please try again later. Reopening the app will re-attempt to create an account.") + /// GO BACK + internal static let submit = L10n.tr("Signup", "failure.submit", fallback: "GO BACK") + /// Account creation failed + internal static let title = L10n.tr("Signup", "failure.title", fallback: "Account creation failed") + /// Sign-up failed + internal static let vcTitle = L10n.tr("Signup", "failure.vc_title", fallback: "Sign-up failed") + internal enum Purchase { + internal enum Sandbox { + /// The selected sandbox subscription is not available in production. + internal static let message = L10n.tr("Signup", "failure.purchase.sandbox.message", fallback: "The selected sandbox subscription is not available in production.") } - internal enum Show { - /// Connection stats - internal static let title = L10n.tr("Localizable", "settings.service.quality.show.title") + } + internal enum Redeem { + internal enum Claimed { + /// Looks like this card has already been claimed by another account. You can try entering a different PIN. + internal static let message = L10n.tr("Signup", "failure.redeem.claimed.message", fallback: "Looks like this card has already been claimed by another account. You can try entering a different PIN.") + /// Card claimed already + internal static let title = L10n.tr("Signup", "failure.redeem.claimed.title", fallback: "Card claimed already") + } + internal enum Invalid { + /// Looks like you entered an invalid card PIN. Please try again. + internal static let message = L10n.tr("Signup", "failure.redeem.invalid.message", fallback: "Looks like you entered an invalid card PIN. Please try again.") + /// Invalid card PIN + internal static let title = L10n.tr("Signup", "failure.redeem.invalid.title", fallback: "Invalid card PIN") } } } - internal enum Small { - internal enum Packets { - /// Will slightly lower the IP packet size to improve compatibility with some routers and mobile networks. - internal static let description = L10n.tr("Localizable", "settings.small.packets.description") - /// Use Small Packets - internal static let title = L10n.tr("Localizable", "settings.small.packets.title") + internal enum InProgress { + /// We're confirming your purchase with our system. It could take a moment so hang in there. + internal static let message = L10n.tr("Signup", "in_progress.message", fallback: "We're confirming your purchase with our system. It could take a moment so hang in there.") + /// Signup.strings + /// PIALibrary + /// + /// Created by Davide De Rosa on 12/7/17. + /// Copyright © 2017 London Trust Media. All rights reserved. + internal static let title = L10n.tr("Signup", "in_progress.title", fallback: "Confirm sign-up") + internal enum Redeem { + /// We're confirming your card PIN with our system. It could take a moment so hang in there. + internal static let message = L10n.tr("Signup", "in_progress.redeem.message", fallback: "We're confirming your card PIN with our system. It could take a moment so hang in there.") + } + } + internal enum Purchase { + internal enum Subscribe { + /// Subscribe now + internal static let now = L10n.tr("Signup", "purchase.subscribe.now", fallback: "Subscribe now") + } + internal enum Trials { + /// Browse anonymously and hide your ip. + internal static let anonymous = L10n.tr("Signup", "purchase.trials.anonymous", fallback: "Browse anonymously and hide your ip.") + /// Support 10 devices at once + internal static let devices = L10n.tr("Signup", "purchase.trials.devices", fallback: "Support 10 devices at once") + /// Start your 7-day free trial + internal static let intro = L10n.tr("Signup", "purchase.trials.intro", fallback: "Start your 7-day free trial") + /// Connect to any region easily + internal static let region = L10n.tr("Signup", "purchase.trials.region", fallback: "Connect to any region easily") + /// More than 3300 servers in 32 countries + internal static let servers = L10n.tr("Signup", "purchase.trials.servers", fallback: "More than 3300 servers in 32 countries") + /// Start subscription + internal static let start = L10n.tr("Signup", "purchase.trials.start", fallback: "Start subscription") + internal enum _1year { + /// 1 year of privacy and identity protection + internal static let protection = L10n.tr("Signup", "purchase.trials.1year.protection", fallback: "1 year of privacy and identity protection") + } + internal enum All { + /// See all available plans + internal static let plans = L10n.tr("Signup", "purchase.trials.all.plans", fallback: "See all available plans") + } + internal enum Devices { + /// Protect yourself on up to 10 devices at a time. + internal static let description = L10n.tr("Signup", "purchase.trials.devices.description", fallback: "Protect yourself on up to 10 devices at a time.") + } + internal enum Money { + /// 30 day money back guarantee + internal static let back = L10n.tr("Signup", "purchase.trials.money.back", fallback: "30 day money back guarantee") + } + internal enum Price { + /// Then %@ + internal static func after(_ p1: Any) -> String { + return L10n.tr("Signup", "purchase.trials.price.after", String(describing: p1), fallback: "Then %@") + } + } + } + internal enum Uncredited { + internal enum Alert { + /// You have uncredited transactions. Do you want to recover your account details? + internal static let message = L10n.tr("Signup", "purchase.uncredited.alert.message", fallback: "You have uncredited transactions. Do you want to recover your account details?") + internal enum Button { + /// Cancel + internal static let cancel = L10n.tr("Signup", "purchase.uncredited.alert.button.cancel", fallback: "Cancel") + /// Recover account + internal static let recover = L10n.tr("Signup", "purchase.uncredited.alert.button.recover", fallback: "Recover account") + } + } } } - internal enum Trusted { - internal enum Networks { - /// PIA won't automatically connect on these networks. - internal static let message = L10n.tr("Localizable", "settings.trusted.networks.message") - internal enum Connect { - /// Protect this network by connecting to VPN? - internal static let message = L10n.tr("Localizable", "settings.trusted.networks.connect.message") - } - internal enum Sections { - /// Available networks - internal static let available = L10n.tr("Localizable", "settings.trusted.networks.sections.available") - /// Current network - internal static let current = L10n.tr("Localizable", "settings.trusted.networks.sections.current") - /// Trusted networks - internal static let trusted = L10n.tr("Localizable", "settings.trusted.networks.sections.trusted") - /// Untrusted networks - internal static let untrusted = L10n.tr("Localizable", "settings.trusted.networks.sections.untrusted") - internal enum Trusted { - internal enum Rule { - /// Disconnect from PIA VPN - internal static let action = L10n.tr("Localizable", "settings.trusted.networks.sections.trusted.rule.action") - /// Enable this feature, with the VPN kill switch enabled, to customize how PIA will behave on WiFi and cellular networks. Please be aware, functionality of the Network Management Tool will be disabled if you manually disconnect. - internal static let description = L10n.tr("Localizable", "settings.trusted.networks.sections.trusted.rule.description") - } + internal enum Share { + internal enum Data { + internal enum Buttons { + /// Accept + internal static let accept = L10n.tr("Signup", "share.data.buttons.accept", fallback: "Accept") + /// No, thanks + internal static let noThanks = L10n.tr("Signup", "share.data.buttons.noThanks", fallback: "No, thanks") + /// Read more + internal static let readMore = L10n.tr("Signup", "share.data.buttons.readMore", fallback: "Read more") + } + internal enum ReadMore { + internal enum Text { + /// This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + /// + /// We will collect information about the following events: + /// + /// - Connection Attempt + /// - Connection Canceled + /// - Connection Established + /// + /// For all of these events, we will collect the following information: + /// - Platform + /// - App version + /// - App type (pre-release or not) + /// - Protocol used + /// - Connection source (manual or using automation) + /// - Time To Connect (time between connecting and connected state) + /// + /// All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + /// + /// You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time. + internal static let description = L10n.tr("Signup", "share.data.readMore.text.description", fallback: "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default.\n\nWe will collect information about the following events:\n\n - Connection Attempt\n - Connection Canceled\n - Connection Established\n\nFor all of these events, we will collect the following information:\n - Platform\n - App version\n - App type (pre-release or not)\n - Protocol used\n - Connection source (manual or using automation)\n - Time To Connect (time between connecting and connected state)\n\nAll events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes.\n\nYou will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time.") } } + internal enum Text { + /// To help us ensure our service's connection performance, you can anonymously share your connection stats with us. These reports do not include any personally identifiable information. + internal static let description = L10n.tr("Signup", "share.data.text.description", fallback: "To help us ensure our service's connection performance, you can anonymously share your connection stats with us. These reports do not include any personally identifiable information.") + /// You can always control this from your settings + internal static let footer = L10n.tr("Signup", "share.data.text.footer", fallback: "You can always control this from your settings") + /// Please help us improve our service + internal static let title = L10n.tr("Signup", "share.data.text.title", fallback: "Please help us improve our service") + } + } + } + internal enum Success { + /// Thank you for signing up with us. We have sent your account username and password at your email address at %@ + internal static func messageFormat(_ p1: Any) -> String { + return L10n.tr("Signup", "success.message_format", String(describing: p1), fallback: "Thank you for signing up with us. We have sent your account username and password at your email address at %@") + } + /// GET STARTED + internal static let submit = L10n.tr("Signup", "success.submit", fallback: "GET STARTED") + /// Purchase complete + internal static let title = L10n.tr("Signup", "success.title", fallback: "Purchase complete") + internal enum Password { + /// Password + internal static let caption = L10n.tr("Signup", "success.password.caption", fallback: "Password") + } + internal enum Redeem { + /// You will receive an email shortly with your username and password. + /// + /// Your login details + internal static let message = L10n.tr("Signup", "success.redeem.message", fallback: "You will receive an email shortly with your username and password.\n\nYour login details") + /// Card redeemed successfully + internal static let title = L10n.tr("Signup", "success.redeem.title", fallback: "Card redeemed successfully") + } + internal enum Username { + /// Username + internal static let caption = L10n.tr("Signup", "success.username.caption", fallback: "Username") + } + } + internal enum Unreachable { + /// No internet connection found. Please confirm that you have an internet connection and hit retry below. + /// + /// You can come back to the app later to finish the process. + internal static let message = L10n.tr("Signup", "unreachable.message", fallback: "No internet connection found. Please confirm that you have an internet connection and hit retry below.\n\nYou can come back to the app later to finish the process.") + /// TRY AGAIN + internal static let submit = L10n.tr("Signup", "unreachable.submit", fallback: "TRY AGAIN") + /// Whoops! + internal static let title = L10n.tr("Signup", "unreachable.title", fallback: "Whoops!") + /// Error + internal static let vcTitle = L10n.tr("Signup", "unreachable.vc_title", fallback: "Error") + } + internal enum Walkthrough { + internal enum Action { + /// DONE + internal static let done = L10n.tr("Signup", "walkthrough.action.done", fallback: "DONE") + /// NEXT + internal static let next = L10n.tr("Signup", "walkthrough.action.next", fallback: "NEXT") + /// SKIP + internal static let skip = L10n.tr("Signup", "walkthrough.action.skip", fallback: "SKIP") + } + internal enum Page { + internal enum _1 { + /// Protect yourself on up to 10 devices at a time. + internal static let description = L10n.tr("Signup", "walkthrough.page.1.description", fallback: "Protect yourself on up to 10 devices at a time.") + /// Support 10 devices at once + internal static let title = L10n.tr("Signup", "walkthrough.page.1.title", fallback: "Support 10 devices at once") + } + internal enum _2 { + /// With servers around the globe, you are always under protection. + internal static let description = L10n.tr("Signup", "walkthrough.page.2.description", fallback: "With servers around the globe, you are always under protection.") + /// Connect to any region easily + internal static let title = L10n.tr("Signup", "walkthrough.page.2.title", fallback: "Connect to any region easily") + } + internal enum _3 { + /// Enabling our Content Blocker prevents ads from showing in Safari. + internal static let description = L10n.tr("Signup", "walkthrough.page.3.description", fallback: "Enabling our Content Blocker prevents ads from showing in Safari.") + /// Protect yourself from ads + internal static let title = L10n.tr("Signup", "walkthrough.page.3.title", fallback: "Protect yourself from ads") + } } } } - - internal enum Shortcuts { - /// Connect - internal static let connect = L10n.tr("Localizable", "shortcuts.connect") - /// Disconnect - internal static let disconnect = L10n.tr("Localizable", "shortcuts.disconnect") - /// Select a region - internal static let selectRegion = L10n.tr("Localizable", "shortcuts.select_region") + internal enum Ui { + internal enum Global { + /// Cancel + internal static let cancel = L10n.tr("UI", "global.cancel", fallback: "Cancel") + /// Close + internal static let close = L10n.tr("UI", "global.close", fallback: "Close") + /// OK + internal static let ok = L10n.tr("UI", "global.ok", fallback: "OK") + internal enum Version { + /// Version %@ (%@) + internal static func format(_ p1: Any, _ p2: Any) -> String { + return L10n.tr("UI", "global.version.format", String(describing: p1), String(describing: p2), fallback: "Version %@ (%@)") + } + } + } } - - internal enum Siri { - internal enum Shortcuts { - internal enum Add { - /// There was an error adding the Siri shortcut. Please, try it again. - internal static let error = L10n.tr("Localizable", "siri.shortcuts.add.error") + internal enum Welcome { + internal enum Agreement { + /// After the 7 days free trial this subscription automatically renews for %@ unless it is canceled at least 24 hours before the end of the trial period. Your Apple ID account will be charged for renewal within 24 hours before the end of the trial period. You can manage and cancel your subscriptions by going to your App Store account settings after purchase. 7-days trial offer is limited to one 7-days trial offer per user. Any unused portion of a free trial period, if offered, will be forfeited when the user purchases a subscription. All prices include applicable local sales taxes. + /// + /// Signing up constitutes acceptance of the $1 and the $2. + internal static func message(_ p1: Any) -> String { + return L10n.tr("Welcome", "agreement.message", String(describing: p1), fallback: "After the 7 days free trial this subscription automatically renews for %@ unless it is canceled at least 24 hours before the end of the trial period. Your Apple ID account will be charged for renewal within 24 hours before the end of the trial period. You can manage and cancel your subscriptions by going to your App Store account settings after purchase. 7-days trial offer is limited to one 7-days trial offer per user. Any unused portion of a free trial period, if offered, will be forfeited when the user purchases a subscription. All prices include applicable local sales taxes.\n\nSigning up constitutes acceptance of the $1 and the $2.") } - internal enum Connect { - /// Connect PIA VPN - internal static let title = L10n.tr("Localizable", "siri.shortcuts.connect.title") - internal enum Row { - /// 'Connect' Siri Shortcut - internal static let title = L10n.tr("Localizable", "siri.shortcuts.connect.row.title") + internal enum Message { + /// Privacy Policy + internal static let privacy = L10n.tr("Welcome", "agreement.message.privacy", fallback: "Privacy Policy") + /// Terms of Service + internal static let tos = L10n.tr("Welcome", "agreement.message.tos", fallback: "Terms of Service") + } + internal enum Trials { + /// Payment will be charged to your Apple ID account at the confirmation of purchase. Subscription automatically renews unless it is canceled at least 24 hours before the end of the current period. Your account will be charged for renewal within 24 hours prior to the end of the current period. You can manage and cancel your subscriptions by going to your account settings on the App Store after purchase. + /// + /// Certain Paid Subscriptions may offer a free trial prior to charging your payment method. If you decide to unsubscribe from a Paid Subscription before we start charging your payment method, cancel the subscription at least 24 hours before the free trial ends. + /// + /// Free trials are only available to new users, and are at our sole discretion, and if you attempt to sign up for an additional free trial, you will be immediately charged with the standard Subscription Fee. + /// + /// We reserve the right to revoke your free trial at any time. + /// + /// Any unused portion of your free trial period will be forfeited upon purchase of a subscription. + /// + /// Signing up constitutes acceptance of this terms and conditions. + internal static let message = L10n.tr("Welcome", "agreement.trials.message", fallback: "Payment will be charged to your Apple ID account at the confirmation of purchase. Subscription automatically renews unless it is canceled at least 24 hours before the end of the current period. Your account will be charged for renewal within 24 hours prior to the end of the current period. You can manage and cancel your subscriptions by going to your account settings on the App Store after purchase.\n\nCertain Paid Subscriptions may offer a free trial prior to charging your payment method. If you decide to unsubscribe from a Paid Subscription before we start charging your payment method, cancel the subscription at least 24 hours before the free trial ends.\n\nFree trials are only available to new users, and are at our sole discretion, and if you attempt to sign up for an additional free trial, you will be immediately charged with the standard Subscription Fee.\n\nWe reserve the right to revoke your free trial at any time.\n\nAny unused portion of your free trial period will be forfeited upon purchase of a subscription.\n\nSigning up constitutes acceptance of this terms and conditions.") + /// Free trials terms and conditions + internal static let title = L10n.tr("Welcome", "agreement.trials.title", fallback: "Free trials terms and conditions") + internal enum Monthly { + /// month + internal static let plan = L10n.tr("Welcome", "agreement.trials.monthly.plan", fallback: "month") } - } - internal enum Disconnect { - /// Disconnect PIA VPN - internal static let title = L10n.tr("Localizable", "siri.shortcuts.disconnect.title") - internal enum Row { - /// 'Disconnect' Siri Shortcut - internal static let title = L10n.tr("Localizable", "siri.shortcuts.disconnect.row.title") + internal enum Yearly { + /// year + internal static let plan = L10n.tr("Welcome", "agreement.trials.yearly.plan", fallback: "year") } } } - } - - internal enum Tiles { - internal enum Accessibility { - internal enum Invisible { - internal enum Tile { - /// Tap to add this tile to the dashboard - internal static let action = L10n.tr("Localizable", "tiles.accessibility.invisible.tile.action") + internal enum Gdpr { + internal enum Accept { + internal enum Button { + /// Agree and continue + internal static let title = L10n.tr("Welcome", "gdpr.accept.button.title", fallback: "Agree and continue") + } + } + internal enum Collect { + internal enum Data { + /// E-mail Address for the purposes of account management and protection from abuse. + internal static let description = L10n.tr("Welcome", "gdpr.collect.data.description", fallback: "E-mail Address for the purposes of account management and protection from abuse.") + /// Personal information we collect + internal static let title = L10n.tr("Welcome", "gdpr.collect.data.title", fallback: "Personal information we collect") } } - internal enum Visible { - internal enum Tile { - /// Tap to remove this tile from the dashboard - internal static let action = L10n.tr("Localizable", "tiles.accessibility.visible.tile.action") + internal enum Usage { + internal enum Data { + /// E-mail address is used to send subscription information, payment confirmations, customer correspondence, and Private Internet Access promotional offers only. + internal static let description = L10n.tr("Welcome", "gdpr.usage.data.description", fallback: "E-mail address is used to send subscription information, payment confirmations, customer correspondence, and Private Internet Access promotional offers only.") + /// Uses of personal information collected by us + internal static let title = L10n.tr("Welcome", "gdpr.usage.data.title", fallback: "Uses of personal information collected by us") } } } - internal enum Favorite { - internal enum Servers { - /// Favorite servers - internal static let title = L10n.tr("Localizable", "tiles.favorite.servers.title") + internal enum Getstarted { + internal enum Buttons { + /// Buy account + internal static let buyaccount = L10n.tr("Welcome", "getstarted.buttons.buyaccount", fallback: "Buy account") } } - internal enum Nmt { - /// Cellular - internal static let cellular = L10n.tr("Localizable", "tiles.nmt.cellular") - internal enum Accessibility { - /// Trusted network - internal static let trusted = L10n.tr("Localizable", "tiles.nmt.accessibility.trusted") - /// Untrusted network - internal static let untrusted = L10n.tr("Localizable", "tiles.nmt.accessibility.untrusted") + internal enum Iap { + internal enum Error { + /// Error + internal static let title = L10n.tr("Welcome", "iap.error.title", fallback: "Error") + internal enum Message { + /// Apple servers currently unavailable. Please try again later. + internal static let unavailable = L10n.tr("Welcome", "iap.error.message.unavailable", fallback: "Apple servers currently unavailable. Please try again later.") + } } } - internal enum Quick { - internal enum Connect { - /// Quick connect - internal static let title = L10n.tr("Localizable", "tiles.quick.connect.title") + internal enum Login { + /// LOGIN + internal static let submit = L10n.tr("Welcome", "login.submit", fallback: "LOGIN") + /// Welcome.strings + /// PIALibrary + /// + /// Created by Davide De Rosa on 12/7/17. + /// Copyright © 2017 London Trust Media. All rights reserved. + internal static let title = L10n.tr("Welcome", "login.title", fallback: "Sign in to your account") + internal enum Error { + /// Too many failed login attempts with this username. Please try again after %@ second(s). + internal static func throttled(_ p1: Any) -> String { + return L10n.tr("Welcome", "login.error.throttled", String(describing: p1), fallback: "Too many failed login attempts with this username. Please try again after %@ second(s).") + } + /// Log in + internal static let title = L10n.tr("Welcome", "login.error.title", fallback: "Log in") + /// Your username or password is incorrect. + internal static let unauthorized = L10n.tr("Welcome", "login.error.unauthorized", fallback: "Your username or password is incorrect.") + /// You must enter a username and password. + internal static let validation = L10n.tr("Welcome", "login.error.validation", fallback: "You must enter a username and password.") + } + internal enum Magic { + internal enum Link { + /// Please check your e-mail for a login link. + internal static let response = L10n.tr("Welcome", "login.magic.link.response", fallback: "Please check your e-mail for a login link.") + /// Send Link + internal static let send = L10n.tr("Welcome", "login.magic.link.send", fallback: "Send Link") + /// Login using magic email link + internal static let title = L10n.tr("Welcome", "login.magic.link.title", fallback: "Login using magic email link") + internal enum Invalid { + /// Invalid email. Please try again. + internal static let email = L10n.tr("Welcome", "login.magic.link.invalid.email", fallback: "Invalid email. Please try again.") + } + } + } + internal enum Password { + /// Password + internal static let placeholder = L10n.tr("Welcome", "login.password.placeholder", fallback: "Password") + } + internal enum Receipt { + /// Login using purchase receipt + internal static let button = L10n.tr("Welcome", "login.receipt.button", fallback: "Login using purchase receipt") + } + internal enum Restore { + /// Didn't receive account details? + internal static let button = L10n.tr("Welcome", "login.restore.button", fallback: "Didn't receive account details?") + } + internal enum Username { + /// Username (p1234567) + internal static let placeholder = L10n.tr("Welcome", "login.username.placeholder", fallback: "Username (p1234567)") } } - internal enum Quicksetting { - internal enum Nmt { - /// Network Management - internal static let title = L10n.tr("Localizable", "tiles.quicksetting.nmt.title") + internal enum Plan { + /// Best value + internal static let bestValue = L10n.tr("Welcome", "plan.best_value", fallback: "Best value") + /// %@/mo + internal static func priceFormat(_ p1: Any) -> String { + return L10n.tr("Welcome", "plan.price_format", String(describing: p1), fallback: "%@/mo") } - internal enum Private { - internal enum Browser { - /// Private Browser - internal static let title = L10n.tr("Localizable", "tiles.quicksetting.private.browser.title") + internal enum Accessibility { + /// per month + internal static let perMonth = L10n.tr("Welcome", "plan.accessibility.per_month", fallback: "per month") + } + internal enum Monthly { + /// Monthly + internal static let title = L10n.tr("Welcome", "plan.monthly.title", fallback: "Monthly") + } + internal enum Yearly { + /// %@%@ per year + internal static func detailFormat(_ p1: Any, _ p2: Any) -> String { + return L10n.tr("Welcome", "plan.yearly.detail_format", String(describing: p1), String(describing: p2), fallback: "%@%@ per year") + } + /// Yearly + internal static let title = L10n.tr("Welcome", "plan.yearly.title", fallback: "Yearly") + } + } + internal enum Purchase { + /// Continue + internal static let `continue` = L10n.tr("Welcome", "purchase.continue", fallback: "Continue") + /// or + internal static let or = L10n.tr("Welcome", "purchase.or", fallback: "or") + /// Submit + internal static let submit = L10n.tr("Welcome", "purchase.submit", fallback: "Submit") + /// 30-day money back guarantee + internal static let subtitle = L10n.tr("Welcome", "purchase.subtitle", fallback: "30-day money back guarantee") + /// Select a VPN plan + internal static let title = L10n.tr("Welcome", "purchase.title", fallback: "Select a VPN plan") + internal enum Confirm { + /// You are purchasing the %@ plan + internal static func plan(_ p1: Any) -> String { + return L10n.tr("Welcome", "purchase.confirm.plan", String(describing: p1), fallback: "You are purchasing the %@ plan") } + internal enum Form { + /// Enter your email address + internal static let email = L10n.tr("Welcome", "purchase.confirm.form.email", fallback: "Enter your email address") + } + } + internal enum Email { + /// Email address + internal static let placeholder = L10n.tr("Welcome", "purchase.email.placeholder", fallback: "Email address") + /// We need your email to send your username and password. + internal static let why = L10n.tr("Welcome", "purchase.email.why", fallback: "We need your email to send your username and password.") + } + internal enum Error { + /// Purchase + internal static let title = L10n.tr("Welcome", "purchase.error.title", fallback: "Purchase") + /// You must enter an email address. + internal static let validation = L10n.tr("Welcome", "purchase.error.validation", fallback: "You must enter an email address.") + internal enum Connectivity { + /// We are unable to reach Private Internet Access. This may due to poor internet or our service is blocked in your country. + internal static let description = L10n.tr("Welcome", "purchase.error.connectivity.description", fallback: "We are unable to reach Private Internet Access. This may due to poor internet or our service is blocked in your country.") + /// Connection Failure + internal static let title = L10n.tr("Welcome", "purchase.error.connectivity.title", fallback: "Connection Failure") + } + } + internal enum Login { + /// Sign in + internal static let button = L10n.tr("Welcome", "purchase.login.button", fallback: "Sign in") + /// Already have an account? + internal static let footer = L10n.tr("Welcome", "purchase.login.footer", fallback: "Already have an account?") } } - internal enum Quicksettings { - /// Quick settings - internal static let title = L10n.tr("Localizable", "tiles.quicksettings.title") - internal enum Min { - internal enum Elements { - /// You should keep at least one element visible in the Quick Settings Tile - internal static let message = L10n.tr("Localizable", "tiles.quicksettings.min.elements.message") + internal enum Redeem { + /// SUBMIT + internal static let submit = L10n.tr("Welcome", "redeem.submit", fallback: "SUBMIT") + /// Type in your email address and the %lu digit PIN from your gift card or trial card below. + internal static func subtitle(_ p1: Int) -> String { + return L10n.tr("Welcome", "redeem.subtitle", p1, fallback: "Type in your email address and the %lu digit PIN from your gift card or trial card below.") + } + /// Redeem gift card + internal static let title = L10n.tr("Welcome", "redeem.title", fallback: "Redeem gift card") + internal enum Accessibility { + /// Back + internal static let back = L10n.tr("Welcome", "redeem.accessibility.back", fallback: "Back") + } + internal enum Email { + /// Email address + internal static let placeholder = L10n.tr("Welcome", "redeem.email.placeholder", fallback: "Email address") + } + internal enum Error { + /// Please type in your email and card PIN. + internal static let allfields = L10n.tr("Welcome", "redeem.error.allfields", fallback: "Please type in your email and card PIN.") + /// Code must be %lu numeric digits. + internal static func code(_ p1: Int) -> String { + return L10n.tr("Welcome", "redeem.error.code", p1, fallback: "Code must be %lu numeric digits.") } + /// Redeem + internal static let title = L10n.tr("Welcome", "redeem.error.title", fallback: "Redeem") + } + internal enum Giftcard { + /// Gift card PIN + internal static let placeholder = L10n.tr("Welcome", "redeem.giftcard.placeholder", fallback: "Gift card PIN") } } - internal enum Region { - /// VPN Server - internal static let title = L10n.tr("Localizable", "tiles.region.title") + internal enum Restore { + /// CONFIRM + internal static let submit = L10n.tr("Welcome", "restore.submit", fallback: "CONFIRM") + /// If you purchased a plan through this app and didn't receive your credentials, you can send them again from here. You will not be charged during this process. + internal static let subtitle = L10n.tr("Welcome", "restore.subtitle", fallback: "If you purchased a plan through this app and didn't receive your credentials, you can send them again from here. You will not be charged during this process.") + /// Restore uncredited purchase + internal static let title = L10n.tr("Welcome", "restore.title", fallback: "Restore uncredited purchase") + internal enum Email { + /// Email address + internal static let placeholder = L10n.tr("Welcome", "restore.email.placeholder", fallback: "Email address") + } } - internal enum Subscription { - /// Monthly - internal static let monthly = L10n.tr("Localizable", "tiles.subscription.monthly") - /// Subscription - internal static let title = L10n.tr("Localizable", "tiles.subscription.title") - /// Trial - internal static let trial = L10n.tr("Localizable", "tiles.subscription.trial") - /// Yearly - internal static let yearly = L10n.tr("Localizable", "tiles.subscription.yearly") - internal enum Days { - /// (%d days left) - internal static func `left`(_ p1: Int) -> String { - return L10n.tr("Localizable", "tiles.subscription.days.left", p1) + internal enum Update { + internal enum Account { + internal enum Email { + /// Failed to modify account email + internal static let error = L10n.tr("Welcome", "update.account.email.error", fallback: "Failed to modify account email") } } } - internal enum Usage { - /// Download - internal static let download = L10n.tr("Localizable", "tiles.usage.download") - /// Usage - internal static let title = L10n.tr("Localizable", "tiles.usage.title") - /// Upload - internal static let upload = L10n.tr("Localizable", "tiles.usage.upload") - internal enum Ipsec { - /// USAGE (Not available on IKEv2) - internal static let title = L10n.tr("Localizable", "tiles.usage.ipsec.title") + internal enum Upgrade { + /// Welcome Back! + internal static let header = L10n.tr("Welcome", "upgrade.header", fallback: "Welcome Back!") + /// In order to use Private Internet Access, you’ll need to renew your subscription. + internal static let title = L10n.tr("Welcome", "upgrade.title", fallback: "In order to use Private Internet Access, you’ll need to renew your subscription.") + internal enum Renew { + /// Renew now + internal static let now = L10n.tr("Welcome", "upgrade.renew.now", fallback: "Renew now") } } } - - internal enum Today { - internal enum Widget { - /// Login - internal static let login = L10n.tr("Localizable", "today.widget.login") - } - } - - internal enum VpnPermission { - /// PIA - internal static let title = L10n.tr("Localizable", "vpn_permission.title") - internal enum Body { - /// We don’t monitor, filter or log any network activity. - internal static let footer = L10n.tr("Localizable", "vpn_permission.body.footer") - /// You’ll see a prompt for PIA VPN and need to allow access to VPN configurations.\nTo proceed tap on “%@”. - internal static func subtitle(_ p1: Any) -> String { - return L10n.tr("Localizable", "vpn_permission.body.subtitle", String(describing: p1)) - } - /// PIA needs access to your VPN profiles to secure your traffic - internal static let title = L10n.tr("Localizable", "vpn_permission.body.title") - } - internal enum Disallow { - /// Contact - internal static let contact = L10n.tr("Localizable", "vpn_permission.disallow.contact") - internal enum Message { - /// We need this permission for the application to function. - internal static let basic = L10n.tr("Localizable", "vpn_permission.disallow.message.basic") - /// You can also get in touch with customer support if you need assistance. - internal static let support = L10n.tr("Localizable", "vpn_permission.disallow.message.support") + + internal enum Widget { + internal enum LiveActivity { + internal enum SelectedProtocol { + /// Protocol + internal static let title = L10n.tr("Localizable", "widget.liveActivity.protocol.title", fallback: "Protocol") + } + internal enum Region { + /// Region + internal static let title = L10n.tr("Localizable", "widget.liveActivity.region.title", fallback: "Region") } } } + } // swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length // swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces @@ -1249,8 +1835,8 @@ internal enum L10n { // MARK: - Implementation Details extension L10n { - private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String { - let format = BundleToken.bundle.localizedString(forKey: key, value: nil, table: table) + private static func tr(_ table: String, _ key: String, _ args: CVarArg..., fallback value: String) -> String { + let format = BundleToken.bundle.localizedString(forKey: key, value: value, table: table) return String(format: format, locale: Locale.current, arguments: args) } } diff --git a/PIA VPN/TermsAndConditionsViewController.swift b/PIA VPN/TermsAndConditionsViewController.swift new file mode 100644 index 000000000..b5b7bc691 --- /dev/null +++ b/PIA VPN/TermsAndConditionsViewController.swift @@ -0,0 +1,63 @@ +// +// TermsAndConditionsViewController.swift +// PIALibrary-iOS +// +// Created by Jose Antonio Blaya Garcia on 08/08/2019. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import PIALibrary + +class TermsAndConditionsViewController: AutolayoutViewController, BrandableNavigationBar { + + @IBOutlet private weak var termsTitleLabel: UILabel! + @IBOutlet private weak var termsLabel: UILabel! + var termsAndConditionsTitle: String! + var termsAndConditions: String! + + override func viewDidLoad() { + super.viewDidLoad() + if #available(iOS 13.0, *) { + self.modalPresentationStyle = .automatic + } + self.termsTitleLabel.text = self.termsAndConditionsTitle + self.termsLabel.text = self.termsAndConditions + self.navigationItem.leftBarButtonItem = UIBarButtonItem( + image: Theme.current.palette.navigationBarBackIcon?.withRenderingMode(.alwaysOriginal), + style: .plain, + target: self, + action: #selector(back(_:)) + ) + self.navigationItem.leftBarButtonItem?.accessibilityLabel = L10n.Welcome.Redeem.Accessibility.back + } + + // MARK: Restylable + + override func viewShouldRestyle() { + super.viewShouldRestyle() + navigationItem.titleView = NavigationLogoView() + Theme.current.applyNavigationBarStyle(to: self) + Theme.current.applyPrincipalBackground(view) + Theme.current.applyBigTitle(termsTitleLabel, appearance: .dark) + Theme.current.applySmallSubtitle(termsLabel) + } + + @IBAction func close(_ sender: Any) { + dismissModal() + } +} diff --git a/PIA VPN/Theme+App.swift b/PIA VPN/Theme+App.swift index e2898e32f..b50c0af6f 100644 --- a/PIA VPN/Theme+App.swift +++ b/PIA VPN/Theme+App.swift @@ -23,7 +23,6 @@ import Foundation import PIALibrary import SideMenu -import FXPageControl import UIKit extension Theme { @@ -168,9 +167,9 @@ extension Theme { public func applyFavoriteUnselectedImage(_ imageView: UIImageView) { if palette.appearance == .dark { - imageView.image = Asset.Piax.Global.favoriteUnselectedDark.image + imageView.image = Asset.Images.Piax.Global.favoriteUnselectedDark.image } else { - imageView.image = Asset.Piax.Global.favoriteUnselected.image + imageView.image = Asset.Images.Piax.Global.favoriteUnselected.image } } @@ -192,8 +191,8 @@ extension Theme { public func noResultsImage() -> UIImage { return palette.appearance == .dark ? - Asset.Piax.Regions.noResultsDark.image : - Asset.Piax.Regions.noResultsLight.image + Asset.Images.Piax.Regions.noResultsDark.image : + Asset.Images.Piax.Regions.noResultsLight.image } public func mapImage() -> UIImage? { @@ -210,24 +209,24 @@ extension Theme { public func dragDropImage() -> UIImage { return palette.appearance == .dark ? - Asset.Piax.Global.dragDropIndicatorDark.image : - Asset.Piax.Global.dragDropIndicatorLight.image + Asset.Images.Piax.Global.dragDropIndicatorDark.image : + Asset.Images.Piax.Global.dragDropIndicatorLight.image } public func activeEyeImage() -> UIImage { return palette.appearance == .dark ? - Asset.Piax.Global.eyeActiveDark.image : - Asset.Piax.Global.eyeActiveLight.image + Asset.Images.Piax.Global.eyeActiveDark.image : + Asset.Images.Piax.Global.eyeActiveLight.image } public func inactiveEyeImage() -> UIImage { return palette.appearance == .dark ? - Asset.Piax.Global.eyeInactiveDark.image : - Asset.Piax.Global.eyeInactiveLight.image + Asset.Images.Piax.Global.eyeInactiveDark.image : + Asset.Images.Piax.Global.eyeInactiveLight.image } public func trashIconImage() -> UIImage { - return palette.appearance == .dark ? Asset.iconTrashDark.image : Asset.iconTrash.image + return palette.appearance == .dark ? Asset.Images.iconTrashDark.image : Asset.Images.iconTrash.image } public func applyLicenseMonospaceFontAndColor(_ textView: UITextView, diff --git a/PIA VPN/Theme+DarkPalette.swift b/PIA VPN/Theme+DarkPalette.swift index 54c38a506..cc09056dd 100644 --- a/PIA VPN/Theme+DarkPalette.swift +++ b/PIA VPN/Theme+DarkPalette.swift @@ -22,6 +22,7 @@ import Foundation import PIALibrary +import UIKit extension Theme.Palette { static var dark: Theme.Palette { @@ -29,10 +30,10 @@ extension Theme.Palette { let palette = Theme.Palette() palette.appearance = Theme.Appearance.dark - palette.logo = Asset.navLogoWhite.image + palette.logo = Asset.Images.navLogoWhite.image palette.secondaryColor = UIColor.piaGrey10 palette.textfieldButtonBackgroundColor = UIColor.black - palette.navigationBarBackIcon = Asset.Piax.Global.iconBack.image + palette.navigationBarBackIcon = Asset.Images.Piax.Global.iconBack.image palette.brandBackground = lightPalette.brandBackground palette.secondaryBackground = .piaGrey5 palette.lineColor = .white diff --git a/PIA VPN/Theme+LightPalette.swift b/PIA VPN/Theme+LightPalette.swift new file mode 100644 index 000000000..c9ace9a24 --- /dev/null +++ b/PIA VPN/Theme+LightPalette.swift @@ -0,0 +1,48 @@ +// +// Theme+LightPalette.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 1/23/18. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import Foundation +import UIKit +import PIALibrary + +extension Theme.Palette { + + /// Light theme. + public static var light: Theme.Palette { + let palette = Theme.Palette() + palette.appearance = Theme.Appearance.light + palette.logo = Asset.Images.navLogo.image + palette.secondaryColor = .white + palette.textfieldButtonBackgroundColor = .white + palette.navigationBarBackIcon = Asset.Ui.Piax.Global.iconBack.image + palette.brandBackground = Macros.color(hex: 0x009a18, alpha: 0xff) + palette.secondaryBackground = .white + palette.principalBackground = .piaGrey1 + palette.lineColor = .piaGreenDark20 + palette.emphasis = Macros.color(hex: 0x29cc41, alpha: 0xff) + palette.accent1 = UIColor.piaOrange + palette.accent2 = Macros.color(hex: 0xe60924, alpha: 0xff) + palette.divider = UIColor(white: 0.0, alpha: 0.2) + palette.overlayAlpha = 0.3 + return palette + } +} diff --git a/PIA VPN/Theme.swift b/PIA VPN/Theme.swift new file mode 100644 index 000000000..65633443a --- /dev/null +++ b/PIA VPN/Theme.swift @@ -0,0 +1,819 @@ +// +// Theme.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/19/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import Foundation +import UIKit +import __PIALibraryNative +import PIALibrary + + +/// Defines the look and feel of the client UI. +public class Theme { + + /// Semantic appearance of an accent. + public enum Appearance { + + /// Dark accent. + case dark + + /// Light accent. + case light + + /// Emphasis accent. + case emphasis + } + + /// Defines theme values related to colors. + public final class Palette { + + /// The appearance type theme + public var appearance: Appearance? + + /// The logo image. + public var logo: UIImage? + + /// The navigation bar back image. + public var navigationBarBackIcon: UIImage? + + /// The light background color. + public var secondaryColor: UIColor + + /// The background color of the buttons inside textfields. + public var textfieldButtonBackgroundColor: UIColor + + /// The brand background color. + public var brandBackground: UIColor + + /// The secondary background color. + public var secondaryBackground: UIColor + + /// The solid light background color. + public var principalBackground: UIColor + + /// The emphasis accent color. + public var emphasis: UIColor + + /// The primary accent color. + public var accent1: UIColor + + /// The secondary accent color. + public var accent2: UIColor + + private var darkText: UIColor + + private var darkTextArray: [UIColor] + + private var lightText: UIColor + + private var lightTextArray: [UIColor] + + /// The solid text color for buttons. + public var solidButtonText: UIColor + + /// The divider color. + public var divider: UIColor + + /// The error color. + public var errorColor: UIColor + + /// The overlay alpha value. + public var overlayAlpha: CGFloat + + /// The line color. + public var lineColor: UIColor + + /// :nodoc: + public init() { + appearance = .light + brandBackground = .green + secondaryColor = .piaGrey10 + secondaryBackground = .white + principalBackground = .piaGrey1 + textfieldButtonBackgroundColor = .white + lineColor = .piaGreenDark20 +// primary = .black + emphasis = .green + accent1 = .piaOrange + accent2 = .red + + darkText = .black + darkTextArray = [ + darkText, + darkText, + darkText + ] + lightText = .white + lightTextArray = [ + lightText, + lightText, + lightText + ] + solidButtonText = .white + divider = .piaGrey1 + errorColor = .piaRed + overlayAlpha = 0.3 + } + + /** + Returns the color for the given relevance and appearance. + + - Precondition: `relevance` lies between 1 and 3 (included). + - Parameter relevance: The color relevance between 1 and 3 (included). + - Parameter appearance: An `Appearance` value. + - Returns: The resulting text color. + */ + public func textColor(forRelevance relevance: Int, appearance: Appearance) -> UIColor { + precondition(relevance >= 1) + precondition(relevance <= 3) + + switch appearance { + case .dark: + return darkTextArray[relevance - 1] + + case .light: + return lightTextArray[relevance - 1] + + case .emphasis: + return emphasis + } + } + } + + /// Defines a theme font typeface. + public final class Typeface { + + /// The font name for regular weight. Defaults to system font. + public var regularName: String? + + /// The font name for medium weight. Defaults to system font. + public var mediumName: String? + + /// The font name for monospace text. + public var monospaceName: String + + /// :nodoc: + public init() { + monospaceName = "Courier New" + } + + private func safeFont(name: String, size: CGFloat) -> UIFont { + guard let font = UIFont(name: name, size: size) else { + fatalError("Cannot load font '\(name)'") + } + return font + } + + /** + Returns a regular-weighted font. + + - Parameter size: The size of the font. + - Returns: A regular-weighted font of the given size. + */ + public func regularFont(size: CGFloat) -> UIFont { + guard let name = regularName else { + return UIFont.systemFont(ofSize: size, weight: .regular) + } + return safeFont(name: name, size: size) + } + + /** + Returns a medium-weighted font. + + - Parameter size: The size of the font. + - Returns: A medium-weighted font of the given size. + */ + public func mediumFont(size: CGFloat) -> UIFont { + guard let name = mediumName else { + return UIFont.systemFont(ofSize: size, weight: .medium) + } + return safeFont(name: name, size: size) + } + + /** + Returns a monospace font. + + - Parameter size: The size of the font. + - Returns: A monospace font of the given size. + */ + public func monospaceFont(size: CGFloat) -> UIFont { + return safeFont(name: monospaceName, size: size) + } + } + + /// The current UI theme. + public static let current = Theme() + + /// The `Palette` holding the theme colors. + public var palette: Palette + + /// The `Typeface` holding the theme fonts. + public var typeface: Typeface + + /// The `ThemeStrategy` for dynamic styling. + public var strategy: ThemeStrategy + + private let cornerRadius: CGFloat + +// private let dotSpacing: CGFloat + + private init() { + palette = .light + typeface = Typeface() + strategy = DefaultThemeStrategy() + + cornerRadius = 4.0 +// dotSpacing = 6.0 + } + + /** + Reloads the theme, every observer of `Notification.Name.PIAThemeDidChange` is notified for refreshing. + + - Postcondition: Posts `Notification.Name.PIAThemeDidChange` notification. + */ + public func reload() { + Macros.postNotification(.PIAThemeDidChange) + } + + // MARK: Backgrounds + + /// :nodoc: + public func applySecondaryBackground(_ view: UIView) { + view.backgroundColor = palette.appearance == .dark ? + palette.secondaryBackground.withAlphaComponent(0.3) : + palette.secondaryBackground + } + + /// :nodoc: + public func applyPrincipalBackground(_ view: UIView) { + view.backgroundColor = palette.principalBackground + } + + /// :nodoc: + public func applyRegionSolidLightBackground(_ view: UIView) { + view.backgroundColor = palette.appearance == .dark ? UIColor.piaGrey6 : palette.principalBackground + } + + /// :nodoc: + public func applyWarningBackground(_ view: UIView) { + view.backgroundColor = palette.accent1 + } + + /// :nodoc: + public func applyMessagesBackground(_ view: UIView) { + view.backgroundColor = palette.appearance == .dark ? UIColor.piaGrey8 : UIColor.piaGrey2 + } + + // MARK: Table View Utils + + /// :nodoc: + public func applyDivider(_ view: UIView) { + view.backgroundColor = palette.divider + } + + /// :nodoc: + public func applyDividerToSeparator(_ tableView: UITableView) { + tableView.separatorColor = palette.divider + } + + // MARK: Images + + /// :nodoc: + public func applyCenteredMap(_ imageView: UIImageView) { + imageView.image = palette.appearance == .dark ? + Asset.Ui.Piax.Global.centeredDarkMap.image : Asset.Ui.Piax.Global.centeredLightMap.image + } + + // MARK: Navigation bar + + /// :nodoc: + public func applyBrandNavigationBar(_ navigationBar: UINavigationBar) { + navigationBar.tintColor = palette.textColor(forRelevance: 1, appearance: .light) + navigationBar.setBackgroundAppearenceColor(palette.brandBackground) + } + + // MARK: Typography + /// :nodoc: + public func applyButtonLabelStyle(_ button: UIButton) { + if palette.appearance == Appearance.light { + button.style(style: TextStyle.textStyle9) + } else { + button.style(style: TextStyle.textStyle6) + } + } + + public func applyButtonLabelMediumStyle(_ button: UIButton) { + if palette.appearance == Appearance.light { + button.style(style: TextStyle.textStyle9Medium) + } else { + button.style(style: TextStyle.textStyle6Medium) + } + } + + public func applyVersionNumberStyle(_ label: UILabel) { + label.style(style: TextStyle.versionNumberStyle) + } + + /// :nodoc: + public func applyTitle(_ label: UILabel, appearance: Appearance) { + if palette.appearance == Appearance.light { + label.style(style: TextStyle.textStyle2) + } else { + label.style(style: TextStyle.textStyle1) + } + } + + /// :nodoc: + public func applyBigTitle(_ label: UILabel, appearance: Appearance) { + if palette.appearance == Appearance.light { + label.style(style: TextStyle.textStyle23) + } else { + label.style(style: TextStyle.textStyle22) + } + } + + /// :nodoc: + public func applySubtitle(_ label: UILabel) { + let textAlignment = label.textAlignment + label.style(style: TextStyle.textStyle8) + label.textAlignment = textAlignment + } + + public func applySmallSubtitle(_ label: UILabel) { + let textAlignment = label.textAlignment + label.style(style: TextStyle.textStyle21) + label.textAlignment = textAlignment + } + + /// :nodoc: + public func applyBody1Monospace(_ textView: UITextView, appearance: Appearance) { + textView.font = typeface.monospaceFont(size: 14.0) + textView.textColor = palette.textColor(forRelevance: 2, appearance: appearance) + } + + /// :nodoc: + public func applySmallInfo(_ label: UILabel, appearance: Appearance) { + if palette.appearance == Appearance.light { + label.style(style: TextStyle.textStyle12) + } else { + label.style(style: TextStyle.textStyle11) + } + } + + /// Method to apply a second style for the same UILabel + /// label.text should be previously set + public func makeSmallLabelToStandOut(_ label: UILabel, + withTextToStandOut textToStandOut: String, + andAppearance appearance: Appearance = Appearance.dark) { + + if let text = label.text { + let rangeSecondText = (text as NSString).range(of: textToStandOut) + let attributedString = NSMutableAttributedString(string: text) + + var foregroundColor = TextStyle.textStyle1.color! + if palette.appearance == Appearance.light { + foregroundColor = TextStyle.textStyle2.color! + } + + attributedString.addAttribute(.foregroundColor, + value: foregroundColor, + range: rangeSecondText) + + label.attributedText = attributedString + } + + } + + /// :nodoc: + public func applyTag(_ label: UILabel, appearance: Appearance) { + label.font = typeface.regularFont(size: 12.0) + label.textColor = palette.textColor(forRelevance: 1, appearance: appearance) + } + + /// :nodoc: + public func applyBlackLabelInBox(_ label: UILabel) { + label.font = typeface.regularFont(size: 12.0) + label.textColor = .black + } + + /// :nodoc: + public func applyList(_ label: UILabel, appearance: Appearance) { + applyList(label, appearance: appearance, relevance: 2) + } + + /// :nodoc: + public func applyList(_ label: UILabel, appearance: Appearance, relevance: Int) { + label.font = typeface.regularFont(size: 15.0) + label.textColor = palette.textColor(forRelevance: relevance, appearance: appearance) + } + + // MARK: Textfields + + /// :nodoc: + public func applyInput(_ textField: UITextField) { // hint is placeholder + + textField.style(style: TextStyle.textStyle8) + textField.backgroundColor = Theme.current.palette.secondaryColor + + if let borderedTextField = textField as? BorderedTextField { + borderedTextField.borderColor = palette.divider + borderedTextField.highlightedBorderColor = palette.emphasis + borderedTextField.highlightsWhileEditing = true + } + } + + /// :nodoc: + public func applyInputError(_ textField: UITextField) { // hint is placeholder + + textField.style(style: TextStyle.textStyle8) + textField.backgroundColor = Theme.current.palette.secondaryColor + + if let borderedTextField = textField as? BorderedTextField { + borderedTextField.borderColor = palette.errorColor + borderedTextField.highlightedBorderColor = palette.errorColor + borderedTextField.highlightsWhileEditing = true + } + } + + // MARK: Buttons + + /// :nodoc: + public func applyTransparentButton(_ button: PIAButton, + withSize size: CGFloat) { + button.setBorder(withSize: size, + andColor: palette.lineColor) + button.setTitleColor(palette.lineColor, + for: .normal) + } + + /// :nodoc: + public func applyActivityIndicator(_ activityIndicator: UIActivityIndicatorView) { + activityIndicator.color = palette.appearance == Appearance.light ? .piaGreen : .piaWhite + } + + /// :nodoc: + public func applyActionButton(_ button: ActivityButton) { + button.font = typeface.mediumFont(size: 15.0) + button.backgroundColor = palette.emphasis + button.textColor = palette.solidButtonText + button.cornerRadius = cornerRadius + } + + /// :nodoc: + public func applyCancelButton(_ button: UIButton, appearance: Appearance) { + button.setTitle("×", for: .normal) + button.titleLabel?.font = typeface.mediumFont(size: 36.0) + button.setTitleColor(palette.textColor(forRelevance: 1, appearance: appearance), for: .normal) + } + + public func applyUnderlinedSubtitleButton(_ button: UIButton) { + button.style(style: TextStyle.textStyle8) + let attributes: [NSAttributedString.Key: Any] = [ + .underlineStyle: NSUnderlineStyle.single.rawValue + ] + let title = button.title(for: .normal) ?? "" + + let attributedString = NSAttributedString(string: title, attributes: attributes) + button.setAttributedTitle(attributedString, for: .normal) + + } + + public func applyUnderline(_ label: UILabel, with text: String) { + label.style(style: TextStyle.textStyle10) + let attributes: [NSAttributedString.Key: Any] = [ + .underlineStyle: NSUnderlineStyle.single.rawValue + ] + + let attributedString = NSAttributedString(string: text, attributes: attributes) + label.attributedText = attributedString + } + + /// :nodoc: + public func agreementText(withMessage message: String, tos: String, tosUrl: String, privacy: String, privacyUrl: String) -> NSAttributedString { + let plain = message.replacingOccurrences( + of: "$1", + with: tos + ).replacingOccurrences( + of: "$2", + with: privacy + ) as NSString + + let attributed = NSMutableAttributedString(string: plain as String) + let paragraph = NSMutableParagraphStyle() + paragraph.alignment = .center + paragraph.minimumLineHeight = 16 + let fullRange = NSMakeRange(0, plain.length) + attributed.addAttribute(.font, value: UIFont.regularFontWith(size: 12), range: fullRange) + attributed.addAttribute(.foregroundColor, value: UIColor.piaGrey4, range: fullRange) + attributed.addAttribute(.paragraphStyle, value: paragraph, range: fullRange) + let range1 = plain.range(of: tos) + let range2 = plain.range(of: privacy) + attributed.addAttribute(.link, value: tosUrl, range: range1) + attributed.addAttribute(.link, value: privacyUrl, range: range2) + return attributed + } + + public func messageWithLinkText(withMessage message: String, link: String) -> NSAttributedString { + let plain = message.replacingOccurrences( + of: "$1", + with: link + ) as NSString + + let attributed = NSMutableAttributedString(string: plain as String) + let paragraph = NSMutableParagraphStyle() + paragraph.alignment = .center + paragraph.minimumLineHeight = 16 + let fullRange = NSMakeRange(0, plain.length) + attributed.addAttribute(.font, value: UIFont.mediumFontWith(size: 14), range: fullRange) + if Theme.current.palette.appearance == .dark { + attributed.addAttribute(.foregroundColor, value: UIColor.white, range: fullRange) + } else { + attributed.addAttribute(.foregroundColor, value: UIColor.piaGrey6, range: fullRange) + } + attributed.addAttribute(.paragraphStyle, value: paragraph, range: fullRange) + let range1 = plain.range(of: link) + attributed.addAttribute(.link, value: link, range: range1) + return attributed + } + + + // MARK: Composite + + /// :nodoc: + public func applyAppearance() { + let navBarAppearance = UINavigationBar.appearance() + let switchAppearance = UISwitch.appearance() + let activityIndicatorAppearance = UIActivityIndicatorView.appearance() + let pageControlAppearance = UIPageControl.appearance() + + switchAppearance.onTintColor = palette.emphasis + activityIndicatorAppearance.color = palette.textColor(forRelevance: 2, appearance: .dark) + pageControlAppearance.pageIndicatorTintColor = UIColor.groupTableViewBackground + pageControlAppearance.currentPageIndicatorTintColor = palette.emphasis + + navBarAppearance.barStyle = .black + navBarAppearance.isTranslucent = false + navBarAppearance.setBackgroundImage(UIImage(), for: .default) + navBarAppearance.shadowImage = UIImage() + } + + /// :nodoc: + public func applyTableSectionHeader(_ view: UIView) { + guard let hfv = view as? UITableViewHeaderFooterView, let label = hfv.textLabel else { + return + } + label.style(style: TextStyle.textStyle14) + } + + /// :nodoc: + public func applyTableSectionFooter(_ view: UIView) { + guard let hfv = view as? UITableViewHeaderFooterView, let label = hfv.textLabel else { + return + } + label.style(style: TextStyle.textStyle21) + } + + /// :nodoc: + public func applyDetailTableCell(_ cell: UITableViewCell) { + if let label = cell.textLabel { + applyList(label, appearance: .dark, relevance: 2) + } + if let detail = cell.detailTextLabel { + applyList(detail, appearance: .dark, relevance: 3) + } + } + + /// :nodoc: + public func applyCorner(_ view: UIView) { + applyCorner(view, factor: 1.0) + } + + /// :nodoc: + public func applyCorner(_ view: UIView, factor: CGFloat) { + view.layer.cornerRadius = cornerRadius * factor +// view.layer.masksToBounds = true + } + + /// :nodoc: + public func applyBorder(_ view: UIView, selected: Bool) { + applyBorder(view, selected: selected, factor: 1.0) + } + + /// :nodoc: + public func applyBorder(_ view: UIView, selected: Bool, factor: CGFloat) { + view.layer.cornerRadius = cornerRadius * factor + view.layer.borderWidth = 1.0 + view.layer.borderColor = (selected ? palette.emphasis : palette.divider).cgColor + view.clipsToBounds = true + } + + /// :nodoc: + public func applyCircleProgressView(_ circleProgressView: CircleProgressView) { + circleProgressView.outerColor = palette.brandBackground + circleProgressView.innerColor = palette.divider + circleProgressView.fixedColor = palette.emphasis + } + + /// :nodoc: + public func applyLinkAttributes(_ textView: UITextView) { + textView.tintColor = palette.lineColor + } + + public func applyMessageLinkAttributes(_ textView: UITextView, withColor color: UIColor) { + textView.tintColor = color + } + + /// :nodoc: + public func applyScrollableMap(_ imageView: UIImageView) { + imageView.image = palette.appearance == .dark ? + Asset.Ui.Piax.Global.scrollableMapDark.image : Asset.Ui.Piax.Global.scrollableMapLight.image + } + + /// :nodoc: + func applyPageControl(_ pageControl: FXPageControl) { + pageControl.dotSpacing = 6.0 + pageControl.selectedDotImage = Asset.Ui.Piax.Global.pagecontrolSelectedDot.image + pageControl.dotImage = Asset.Ui.Piax.Global.pagecontrolUnselectedDot.image + } + + + // MARK: Strategy + + /// :nodoc: + func applyNavigationBarStyle(to viewController: AutolayoutViewController) { + strategy.applyNavigationBarStyle(to: viewController, theme: self) + } + + /// :nodoc: + func statusBarAppearance(for viewController: AutolayoutViewController) -> UIStatusBarStyle { + return strategy.statusBarAppearance(for: viewController) + } + + /// :nodoc: + func autolayoutContainerMargins(for mask: UIInterfaceOrientationMask) -> UIEdgeInsets { + return strategy.autolayoutContainerMargins(for: mask) + } + + // MARK: Navigation bar + + public func applyLightNavigationBar(_ navigationBar: UINavigationBar) { + navigationBar.setBackgroundAppearenceColor(palette.principalBackground) + navigationBar.tintColor = UIColor.piaGrey4 + + } + + // MARK: Refresh control + public func applyRefreshControlStyle(_ refreshControl: UIRefreshControl) { + if palette.appearance == Appearance.light { + refreshControl.style(style: ViewStyle.refreshControlLight) + } else { + refreshControl.style(style: ViewStyle.refreshControlDark) + } + } + + /** + Set color values for a custom navigation bar. + + - Parameter navigationBar: The navigationBar where the changes are going to be applied. + - Parameter tintColor: The tintColor for the navigationBar. If nil: self.palette.textColor(forRelevance: 1, appearance: .dark) + - Parameter barTintColors: Array of colors for the background of the navigationBar. If the array contains 2 colors, it will generate a gradient. If the array contains more than 2 colors or nil, it will set the default value: self.palette.secondaryBackground. If the array only contains 1 color, a solid background color will be set. + */ + public func applyCustomNavigationBar(_ navigationBar: UINavigationBar, + withTintColor tintColor: UIColor?, + andBarTintColors barTintColors: [UIColor]?) { + + UIView.animate(withDuration: 0.3) { + if let tintColor = tintColor { + navigationBar.tintColor = tintColor + } else { + navigationBar.tintColor = UIColor.piaGrey4 + } + + if let barTintColors = barTintColors, + barTintColors.count > 0, + barTintColors.count <= 2 { + if barTintColors.count == 1 { + navigationBar.setBackgroundAppearenceColor(barTintColors.first) + navigationBar.setBackgroundAppearenceImage(nil) + } else { + var updatedFrame = navigationBar.bounds + updatedFrame.size.height += navigationBar.frame.origin.y + let gradientLayer = CAGradientLayer(frame: updatedFrame, colors: barTintColors) + navigationBar.setBackgroundAppearenceImage(gradientLayer.createGradientImage()) + } + } else { + navigationBar.setBackgroundAppearenceColor(self.palette.principalBackground) + navigationBar.setBackgroundAppearenceImage(nil) + } + navigationBar.setNeedsLayout() + } + + } + + + public func applyLightBrandLogoNavigationBar(_ navigationBar: UINavigationBar) { + navigationBar.tintColor = palette.textColor(forRelevance: 1, appearance: .dark) + navigationBar.setBackgroundAppearenceColor(palette.principalBackground) + } + + //MARK: Cell + /// :nodoc: + public func applySettingsCellTitle(_ label: UILabel, appearance: Appearance) { + if palette.appearance == Appearance.light { + label.style(style: TextStyle.textStyle7) + } else { + label.style(style: TextStyle.textStyle6) + } + } + + /// :nodoc: + public func applyRegionIPCell(_ label: UILabel, appearance: Appearance) { + label.style(style: TextStyle.ipTextStyle) + } + + public func applyRegionIPTitleCell(_ label: UILabel, appearance: Appearance) { + label.style(style: TextStyle.ipTitleTextStyle) + } + + //MARK: Tile Usage + /// :nodoc: + public func applySubtitleTileUsage(_ label: UILabel, appearance: Appearance) { + if palette.appearance == Appearance.dark { + label.style(style: TextStyle.textStyle16) + } else { + label.style(style: TextStyle.textStyle17) + } + } + +} + +/// Defines a dynamic strategy for complex styles. +/// +/// - Seealso: `Theme.strategy` +public protocol ThemeStrategy { + + /** + Applies a style to a `UINavigation` based on an input `AutolayoutViewController`, in order to provide per-controller navigation bar styling. + + - Parameter viewController: The target `AutolayoutViewController` to apply the navigation bar style to. + - Parameter theme: The `Theme` to apply. + */ + func applyNavigationBarStyle(to viewController: AutolayoutViewController, theme: Theme) + + /** + Returns a `UIStatusBarStyle` based on an input `AutolayoutViewController`, in order to provide per-controller styling. + + - Parameter viewController: The target `AutolayoutViewController` to apply the status bar style to. + - Returns: The desired `UIStatusBarStyle` on the given view controller. + */ + func statusBarAppearance(for viewController: AutolayoutViewController) -> UIStatusBarStyle + + /** + Returns a set of margins to apply to `AutolayoutViewController.viewContainer` in a specific orientation mask. + + - Parameter mask: The current `UIInterfaceOrientationMask`. + - Returns: The desired `UIEdgeInsets` margins to apply to `AutolayoutViewController.viewContainer`. + */ + func autolayoutContainerMargins(for mask: UIInterfaceOrientationMask) -> UIEdgeInsets +} + +private struct DefaultThemeStrategy: ThemeStrategy { + func applyNavigationBarStyle(to viewController: AutolayoutViewController, theme: Theme) { + guard let navigationBar = viewController.navigationController?.navigationBar else { + return + } + theme.applyBrandNavigationBar(navigationBar) + } + + func statusBarAppearance(for viewController: AutolayoutViewController) -> UIStatusBarStyle { + if let _ = viewController as? PIAWelcomeViewController { + return .default + } + if let _ = viewController as? GetStartedViewController { + return .default + } + return .lightContent + } + + func autolayoutContainerMargins(for mask: UIInterfaceOrientationMask) -> UIEdgeInsets { + return .zero + } +} diff --git a/PIA VPN/ThemeStrategy+App.swift b/PIA VPN/ThemeStrategy+App.swift index d61a62006..244189e05 100644 --- a/PIA VPN/ThemeStrategy+App.swift +++ b/PIA VPN/ThemeStrategy+App.swift @@ -22,6 +22,7 @@ import Foundation import PIALibrary +import UIKit extension ThemeCode { func apply(theme: Theme, reload: Bool) { diff --git a/PIA VPN/Tiles/ConnectionTile.swift b/PIA VPN/Tiles/ConnectionTile.swift index c3fc8a05a..1bca483e2 100644 --- a/PIA VPN/Tiles/ConnectionTile.swift +++ b/PIA VPN/Tiles/ConnectionTile.swift @@ -21,7 +21,8 @@ import UIKit import PIALibrary -import TunnelKit +import TunnelKitCore +import TunnelKitOpenVPN import WidgetKit class ConnectionTile: UIView, Tileable { @@ -68,7 +69,7 @@ class ConnectionTile: UIView, Tileable { setConnectionValues() viewShouldRestyle() - self.tileTitle.text = L10n.Settings.Connection.title.uppercased() + self.tileTitle.text = L10n.Localizable.Settings.Connection.title.uppercased() } @@ -102,12 +103,12 @@ class ConnectionTile: UIView, Tileable { self.socketLabel.text = "---" self.handshakeLabel.text = "---" - self.protocolLabel.accessibilityLabel = L10n.Global.empty - self.portLabel.accessibilityLabel = L10n.Global.empty - self.authenticationLabel.accessibilityLabel = L10n.Global.empty - self.encryptionLabel.accessibilityLabel = L10n.Global.empty - self.socketLabel.accessibilityLabel = L10n.Global.empty - self.handshakeLabel.accessibilityLabel = L10n.Global.empty + self.protocolLabel.accessibilityLabel = L10n.Localizable.Global.empty + self.portLabel.accessibilityLabel = L10n.Localizable.Global.empty + self.authenticationLabel.accessibilityLabel = L10n.Localizable.Global.empty + self.encryptionLabel.accessibilityLabel = L10n.Localizable.Global.empty + self.socketLabel.accessibilityLabel = L10n.Localizable.Global.empty + self.handshakeLabel.accessibilityLabel = L10n.Localizable.Global.empty } @objc private func viewShouldRestyle() { diff --git a/PIA VPN/Tiles/ConnectionTileCollectionViewCell.swift b/PIA VPN/Tiles/ConnectionTileCollectionViewCell.swift index 2310513e2..f589d7026 100644 --- a/PIA VPN/Tiles/ConnectionTileCollectionViewCell.swift +++ b/PIA VPN/Tiles/ConnectionTileCollectionViewCell.swift @@ -62,11 +62,11 @@ class ConnectionTileCollectionViewCell: UICollectionViewCell, TileableCell { if Client.providers.tileProvider.visibleTiles.contains(tileType) { accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Visible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Visible.Tile.action } else { accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Invisible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Invisible.Tile.action } } diff --git a/PIA VPN/Tiles/FavoriteServersTile.swift b/PIA VPN/Tiles/FavoriteServersTile.swift index a0e57ab10..b25b09fe3 100644 --- a/PIA VPN/Tiles/FavoriteServersTile.swift +++ b/PIA VPN/Tiles/FavoriteServersTile.swift @@ -23,6 +23,7 @@ import Foundation import PIALibrary +import UIKit class FavoriteServersTile: UIView, Tileable { @@ -62,7 +63,7 @@ class FavoriteServersTile: UIView, Tileable { nc.addObserver(self, selector: #selector(updateFavoriteList), name: .PIAServerHasBeenUpdated, object: nil) viewShouldRestyle() - self.tileTitle.text = L10n.Tiles.Favorite.Servers.title.uppercased() + self.tileTitle.text = L10n.Localizable.Tiles.Favorite.Servers.title.uppercased() updateFavoriteList() } @@ -77,18 +78,18 @@ class FavoriteServersTile: UIView, Tileable { currentServers.append(Server.automatic) for containerView in stackView.subviews { if let button = containerView.subviews.first as? ServerButton { - button.setImage(Theme.current.palette.appearance == .light ? Asset.Piax.Tiles.quickConnectPlaceholderLight.image : - Asset.Piax.Tiles.quickConnectPlaceholderDark.image, for: .normal) + button.setImage(Theme.current.palette.appearance == .light ? Asset.Images.Piax.Tiles.quickConnectPlaceholderLight.image : + Asset.Images.Piax.Tiles.quickConnectPlaceholderDark.image, for: .normal) button.imageView?.contentMode = .scaleAspectFit button.isUserInteractionEnabled = false - button.accessibilityLabel = L10n.Global.empty + button.accessibilityLabel = L10n.Localizable.Global.empty } } for label in labelsStackView.subviews { if let label = label as? UILabel { label.text = "" - label.accessibilityLabel = L10n.Global.empty + label.accessibilityLabel = L10n.Localizable.Global.empty } } diff --git a/PIA VPN/Tiles/FavoriteServersTileCollectionViewCell.swift b/PIA VPN/Tiles/FavoriteServersTileCollectionViewCell.swift index 859b0332b..20d7336b9 100644 --- a/PIA VPN/Tiles/FavoriteServersTileCollectionViewCell.swift +++ b/PIA VPN/Tiles/FavoriteServersTileCollectionViewCell.swift @@ -73,11 +73,11 @@ class FavoriteServersTileCollectionViewCell: UICollectionViewCell, TileableCell, if Client.providers.tileProvider.visibleTiles.contains(tileType) { accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Visible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Visible.Tile.action } else { accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Invisible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Invisible.Tile.action } } diff --git a/PIA VPN/Tiles/IPTile.swift b/PIA VPN/Tiles/IPTile.swift index ae68bfe85..2777bec48 100644 --- a/PIA VPN/Tiles/IPTile.swift +++ b/PIA VPN/Tiles/IPTile.swift @@ -66,9 +66,9 @@ class IPTile: UIView, Tileable { self.localIpTitle.text = "IP" self.vpnIpTitle.text = "VPN IP" self.localIpValue.text = Client.daemons.publicIP ?? emptyIPValue - self.localIpValue.accessibilityLabel = Client.daemons.publicIP ?? L10n.Global.empty + self.localIpValue.accessibilityLabel = Client.daemons.publicIP ?? L10n.Localizable.Global.empty self.vpnIpValue.text = emptyIPValue - self.vpnIpValue.accessibilityLabel = L10n.Global.empty + self.vpnIpValue.accessibilityLabel = L10n.Localizable.Global.empty } @@ -85,9 +85,9 @@ class IPTile: UIView, Tileable { let vpn = Client.providers.vpnProvider if (vpn.vpnStatus == .connected) { self.vpnIpValue.text = Client.daemons.vpnIP ?? self.emptyIPValue - self.vpnIpValue.accessibilityLabel = Client.daemons.vpnIP ?? L10n.Global.empty + self.vpnIpValue.accessibilityLabel = Client.daemons.vpnIP ?? L10n.Localizable.Global.empty } else if (!Client.daemons.isInternetReachable && (vpn.vpnStatus == .disconnected)) { - self.vpnIpValue.text = L10n.Dashboard.Connection.Ip.unreachable + self.vpnIpValue.text = L10n.Localizable.Dashboard.Connection.Ip.unreachable } } @@ -96,7 +96,7 @@ class IPTile: UIView, Tileable { switch vpn.vpnStatus { case .connecting, .disconnecting, .disconnected: self.vpnIpValue.text = self.emptyIPValue - self.vpnIpValue.accessibilityLabel = L10n.Global.empty + self.vpnIpValue.accessibilityLabel = L10n.Localizable.Global.empty default: break } diff --git a/PIA VPN/Tiles/IPTileCollectionViewCell.swift b/PIA VPN/Tiles/IPTileCollectionViewCell.swift index b7fdf2ac2..9ed24b9e4 100644 --- a/PIA VPN/Tiles/IPTileCollectionViewCell.swift +++ b/PIA VPN/Tiles/IPTileCollectionViewCell.swift @@ -64,11 +64,11 @@ class IPTileCollectionViewCell: UICollectionViewCell, TileableCell { if Client.providers.tileProvider.visibleTiles.contains(tileType) { accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Visible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Visible.Tile.action } else { accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Invisible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Invisible.Tile.action } } diff --git a/PIA VPN/Tiles/MessagesTile.swift b/PIA VPN/Tiles/MessagesTile.swift index b1e5a1ec8..29700b8af 100644 --- a/PIA VPN/Tiles/MessagesTile.swift +++ b/PIA VPN/Tiles/MessagesTile.swift @@ -21,6 +21,7 @@ import Foundation import PIALibrary +import UIKit class MessagesTile: UIView, Tileable { @@ -57,7 +58,7 @@ class MessagesTile: UIView, Tileable { nc.addObserver(self, selector: #selector(viewShouldRestyle), name: .PIAThemeDidChange, object: nil) viewShouldRestyle() - self.alertIcon.image = Asset.iconAlert.image.withRenderingMode(.alwaysTemplate) + self.alertIcon.image = Asset.Images.iconAlert.image.withRenderingMode(.alwaysTemplate) if let message = MessagesManager.shared.availableMessage(), let _ = message.linkMessage { let tap = UITapGestureRecognizer(target: self, action: #selector(openLink)) diff --git a/PIA VPN/Tiles/QuickConnectTile.swift b/PIA VPN/Tiles/QuickConnectTile.swift index f039d3322..93efb14d0 100644 --- a/PIA VPN/Tiles/QuickConnectTile.swift +++ b/PIA VPN/Tiles/QuickConnectTile.swift @@ -66,7 +66,7 @@ class QuickConnectTile: UIView, Tileable { nc.addObserver(self, selector: #selector(updateQuickConnectList), name: .PIAServerHasBeenUpdated, object: nil) nc.addObserver(self, selector: #selector(updateQuickConnectList), name: .PIADaemonsDidPingServers, object: nil) viewShouldRestyle() - self.tileTitle.text = L10n.Tiles.Quick.Connect.title.uppercased() + self.tileTitle.text = L10n.Localizable.Tiles.Quick.Connect.title.uppercased() updateQuickConnectList() } @@ -113,11 +113,11 @@ class QuickConnectTile: UIView, Tileable { for containerView in stackView.subviews { if let button = containerView.subviews.first as? ServerButton, let favoriteImage = containerView.subviews.last as? UIImageView { - button.setImage(Theme.current.palette.appearance == .light ? Asset.Piax.Tiles.quickConnectPlaceholderLight.image : - Asset.Piax.Tiles.quickConnectPlaceholderDark.image, for: .normal) + button.setImage(Theme.current.palette.appearance == .light ? Asset.Images.Piax.Tiles.quickConnectPlaceholderLight.image : + Asset.Images.Piax.Tiles.quickConnectPlaceholderDark.image, for: .normal) button.imageView?.contentMode = .scaleAspectFit button.isUserInteractionEnabled = false - button.accessibilityLabel = L10n.Global.empty + button.accessibilityLabel = L10n.Localizable.Global.empty favoriteImage.isHidden = true } } @@ -125,7 +125,7 @@ class QuickConnectTile: UIView, Tileable { for label in labelsStackView.subviews { if let label = label as? UILabel { label.text = "" - label.accessibilityLabel = L10n.Global.empty + label.accessibilityLabel = L10n.Localizable.Global.empty } } diff --git a/PIA VPN/Tiles/QuickConnectTileCollectionViewCell.swift b/PIA VPN/Tiles/QuickConnectTileCollectionViewCell.swift index 7b6a7fc23..df1a56ee8 100644 --- a/PIA VPN/Tiles/QuickConnectTileCollectionViewCell.swift +++ b/PIA VPN/Tiles/QuickConnectTileCollectionViewCell.swift @@ -73,11 +73,11 @@ class QuickConnectTileCollectionViewCell: UICollectionViewCell, TileableCell, Se if Client.providers.tileProvider.visibleTiles.contains(tileType) { accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Visible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Visible.Tile.action } else { accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Invisible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Invisible.Tile.action } } diff --git a/PIA VPN/Tiles/QuickSettingsTile.swift b/PIA VPN/Tiles/QuickSettingsTile.swift index 8d59d89ca..90f138034 100644 --- a/PIA VPN/Tiles/QuickSettingsTile.swift +++ b/PIA VPN/Tiles/QuickSettingsTile.swift @@ -68,7 +68,7 @@ class QuickSettingsTile: UIView, Tileable { nc.addObserver(self, selector: #selector(setupButtons), name: .PIAQuickSettingsHaveChanged, object: nil) nc.addObserver(self, selector: #selector(setupButtons), name: .PIATilesDidChange, object: nil) - self.tileTitle.text = L10n.Tiles.Quicksettings.title.uppercased() + self.tileTitle.text = L10n.Localizable.Tiles.Quicksettings.title.uppercased() setupButtons() viewShouldRestyle() @@ -91,42 +91,42 @@ class QuickSettingsTile: UIView, Tileable { @objc private func updateButtons() { - killSwitchButton.accessibilityLabel = L10n.Settings.ApplicationSettings.KillSwitch.title - nmtButton.accessibilityLabel = L10n.Tiles.Quicksetting.Nmt.title - browserButton.accessibilityLabel = L10n.Tiles.Quicksetting.Private.Browser.title + killSwitchButton.accessibilityLabel = L10n.Localizable.Settings.ApplicationSettings.KillSwitch.title + nmtButton.accessibilityLabel = L10n.Localizable.Tiles.Quicksetting.Nmt.title + browserButton.accessibilityLabel = L10n.Localizable.Tiles.Quicksetting.Private.Browser.title if Flags.shared.enablesThemeSwitch { - themeButton.accessibilityLabel = L10n.Settings.ApplicationSettings.ActiveTheme.title + themeButton.accessibilityLabel = L10n.Localizable.Settings.ApplicationSettings.ActiveTheme.title if AppPreferences.shared.currentThemeCode == ThemeCode.light { - themeButton.setImage(Theme.current.palette.appearance == .light ? Asset.Piax.Global.themeLightActive.image : - Asset.Piax.Global.themeDarkActive.image, for: []) + themeButton.setImage(Theme.current.palette.appearance == .light ? Asset.Images.Piax.Global.themeLightActive.image : + Asset.Images.Piax.Global.themeDarkActive.image, for: []) } else { - themeButton.setImage(Theme.current.palette.appearance == .light ? Asset.Piax.Global.themeLightInactive.image : - Asset.Piax.Global.themeDarkInactive.image, for: []) + themeButton.setImage(Theme.current.palette.appearance == .light ? Asset.Images.Piax.Global.themeLightInactive.image : + Asset.Images.Piax.Global.themeDarkInactive.image, for: []) } } if Client.preferences.isPersistentConnection { - killSwitchButton.accessibilityLabel = L10n.Global.disable + " " + L10n.Settings.ApplicationSettings.KillSwitch.title - killSwitchButton.setImage(Asset.Piax.Global.killswitchDarkActive.image, for: []) + killSwitchButton.accessibilityLabel = L10n.Localizable.Global.disable + " " + L10n.Localizable.Settings.ApplicationSettings.KillSwitch.title + killSwitchButton.setImage(Asset.Images.Piax.Global.killswitchDarkActive.image, for: []) } else { - killSwitchButton.accessibilityLabel = L10n.Global.enable + " " + L10n.Settings.ApplicationSettings.KillSwitch.title - killSwitchButton.setImage(Theme.current.palette.appearance == .light ? Asset.Piax.Global.killswitchLightInactive.image : - Asset.Piax.Global.killswitchDarkInactive.image, for: []) + killSwitchButton.accessibilityLabel = L10n.Localizable.Global.enable + " " + L10n.Localizable.Settings.ApplicationSettings.KillSwitch.title + killSwitchButton.setImage(Theme.current.palette.appearance == .light ? Asset.Images.Piax.Global.killswitchLightInactive.image : + Asset.Images.Piax.Global.killswitchDarkInactive.image, for: []) } if Client.preferences.nmtRulesEnabled { - nmtButton.accessibilityLabel = L10n.Global.disable + " " + L10n.Tiles.Quicksetting.Nmt.title - nmtButton.setImage(Theme.current.palette.appearance == .light ? Asset.Piax.Global.nmtLightActive.image : - Asset.Piax.Global.nmtDarkActive.image, for: []) + nmtButton.accessibilityLabel = L10n.Localizable.Global.disable + " " + L10n.Localizable.Tiles.Quicksetting.Nmt.title + nmtButton.setImage(Theme.current.palette.appearance == .light ? Asset.Images.Piax.Global.nmtLightActive.image : + Asset.Images.Piax.Global.nmtDarkActive.image, for: []) } else { - nmtButton.accessibilityLabel = L10n.Global.enable + " " + L10n.Tiles.Quicksetting.Nmt.title - nmtButton.setImage(Theme.current.palette.appearance == .light ? Asset.Piax.Global.nmtLightInactive.image : - Asset.Piax.Global.nmtDarkInactive.image, for: []) + nmtButton.accessibilityLabel = L10n.Localizable.Global.enable + " " + L10n.Localizable.Tiles.Quicksetting.Nmt.title + nmtButton.setImage(Theme.current.palette.appearance == .light ? Asset.Images.Piax.Global.nmtLightInactive.image : + Asset.Images.Piax.Global.nmtDarkInactive.image, for: []) } - browserButton.setImage(Theme.current.palette.appearance == .light ? Asset.Piax.Global.browserLightInactive.image : - Asset.Piax.Global.browserDarkInactive.image, for: []) + browserButton.setImage(Theme.current.palette.appearance == .light ? Asset.Images.Piax.Global.browserLightInactive.image : + Asset.Images.Piax.Global.browserDarkInactive.image, for: []) } diff --git a/PIA VPN/Tiles/QuickSettingsTileCollectionViewCell.swift b/PIA VPN/Tiles/QuickSettingsTileCollectionViewCell.swift index 9d6c2d8ea..e50c27763 100644 --- a/PIA VPN/Tiles/QuickSettingsTileCollectionViewCell.swift +++ b/PIA VPN/Tiles/QuickSettingsTileCollectionViewCell.swift @@ -46,6 +46,7 @@ class QuickSettingsTileCollectionViewCell: UICollectionViewCell, TileableCell { } func setupCellForStatus(_ status: TileStatus) { + self.accessibilityIdentifier = "QuickSettingsTileCollectionViewCell" Theme.current.applyPrincipalBackground(self) Theme.current.applyPrincipalBackground(self.contentView) self.accessoryImageRight.image = Theme.current.dragDropImage() @@ -56,7 +57,7 @@ class QuickSettingsTileCollectionViewCell: UICollectionViewCell, TileableCell { case .normal: self.accessibilityTraits = UIAccessibilityTraits.button self.isAccessibilityElement = true - self.accessoryImageRight.image = Asset.Piax.Tiles.openTileDetails.image + self.accessoryImageRight.image = Asset.Images.Piax.Tiles.openTileDetails.image self.tileLeftConstraint.constant = 0 self.accessoryButtonLeft.isHidden = true case .edit: @@ -76,11 +77,11 @@ class QuickSettingsTileCollectionViewCell: UICollectionViewCell, TileableCell { if Client.providers.tileProvider.visibleTiles.contains(tileType) { accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Visible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Visible.Tile.action } else { accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Invisible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Invisible.Tile.action } } diff --git a/PIA VPN/Tiles/RegionTile.swift b/PIA VPN/Tiles/RegionTile.swift index 17d0f3af2..4cdb77d8c 100644 --- a/PIA VPN/Tiles/RegionTile.swift +++ b/PIA VPN/Tiles/RegionTile.swift @@ -77,7 +77,7 @@ class RegionTile: UIView, Tileable { nc.addObserver(self, selector: #selector(updateServer), name: .PIAServerHasBeenUpdated, object: nil) viewShouldRestyle() - self.tileTitle.text = L10n.Tiles.Region.title.uppercased() + self.tileTitle.text = L10n.Localizable.Tiles.Region.title.uppercased() self.updateServer() } @@ -105,7 +105,7 @@ class RegionTile: UIView, Tileable { labelDedicatedIPTitle.isHidden = false viewIP.isHidden = false labelIP.text = server.wireGuardAddressesForUDP?.first?.ip ?? "" - labelDedicatedIPTitle.text = L10n.Dedicated.Ip.title.uppercased() + labelDedicatedIPTitle.text = L10n.Localizable.Dedicated.Ip.title.uppercased() viewIP.layer.cornerRadius = 10.0 viewIP.layer.borderWidth = 0.5 viewIP.layer.borderColor = UIColor.piaGrey4.cgColor diff --git a/PIA VPN/Tiles/RegionTileCollectionViewCell.swift b/PIA VPN/Tiles/RegionTileCollectionViewCell.swift index 64a9289f5..5724b5c7b 100644 --- a/PIA VPN/Tiles/RegionTileCollectionViewCell.swift +++ b/PIA VPN/Tiles/RegionTileCollectionViewCell.swift @@ -46,7 +46,7 @@ class RegionTileCollectionViewCell: UICollectionViewCell, TileableCell { } func setupCellForStatus(_ status: TileStatus) { - self.accessibilityLabel = L10n.Tiles.Region.title + self.accessibilityLabel = L10n.Localizable.Tiles.Region.title Theme.current.applyPrincipalBackground(self) Theme.current.applyPrincipalBackground(self.contentView) tile.status = status @@ -56,7 +56,7 @@ class RegionTileCollectionViewCell: UICollectionViewCell, TileableCell { case .normal: self.accessibilityTraits = UIAccessibilityTraits.button self.isAccessibilityElement = true - self.accessoryImageRight.image = Asset.Piax.Tiles.openTileDetails.image + self.accessoryImageRight.image = Asset.Images.Piax.Tiles.openTileDetails.image self.tileLeftConstraint.constant = 0 self.accessoryButtonLeft.isHidden = true case .edit: @@ -93,11 +93,11 @@ class RegionTileCollectionViewCell: UICollectionViewCell, TileableCell { if Client.providers.tileProvider.visibleTiles.contains(tileType) { accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Visible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Visible.Tile.action } else { accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Invisible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Invisible.Tile.action } } diff --git a/PIA VPN/Tiles/SubscriptionTile.swift b/PIA VPN/Tiles/SubscriptionTile.swift index a9bdb6314..390a59aeb 100644 --- a/PIA VPN/Tiles/SubscriptionTile.swift +++ b/PIA VPN/Tiles/SubscriptionTile.swift @@ -55,7 +55,7 @@ class SubscriptionTile: UIView, Tileable { nc.addObserver(self, selector: #selector(displayAccountInformation), name: .PIAAccountDidRefresh, object: nil) viewShouldRestyle() - self.subscriptionTitle.text = L10n.Tiles.Subscription.title.uppercased() + self.subscriptionTitle.text = L10n.Localizable.Tiles.Subscription.title.uppercased() displayAccountInformation() } @@ -71,11 +71,11 @@ class SubscriptionTile: UIView, Tileable { if let userInfo = currentUser?.info { if userInfo.isExpired { - self.subscriptionValue.text = L10n.Account.ExpiryDate.expired + self.subscriptionValue.text = L10n.Localizable.Account.ExpiryDate.expired } else { - var value = L10n.Account.ExpiryDate.information(userInfo.humanReadableExpirationDate()) + var value = L10n.Localizable.Account.ExpiryDate.information(userInfo.humanReadableExpirationDate()) if let days = daysLeftFromAccountInfo(userInfo) { - let daysLeft = L10n.Tiles.Subscription.Days.left(days) + let daysLeft = L10n.Localizable.Tiles.Subscription.Days.left(days) let plan = planDescriptionFromPlan(userInfo.plan) if plan != "" { value = plan + " " + daysLeft @@ -91,9 +91,9 @@ class SubscriptionTile: UIView, Tileable { private func planDescriptionFromPlan(_ plan: Plan) -> String { switch plan { - case .trial: return L10n.Tiles.Subscription.trial - case .monthly: return L10n.Tiles.Subscription.monthly - case .yearly: return L10n.Tiles.Subscription.yearly + case .trial: return L10n.Localizable.Tiles.Subscription.trial + case .monthly: return L10n.Localizable.Tiles.Subscription.monthly + case .yearly: return L10n.Localizable.Tiles.Subscription.yearly default: return "" } } diff --git a/PIA VPN/Tiles/SubscriptionTileCollectionViewCell.swift b/PIA VPN/Tiles/SubscriptionTileCollectionViewCell.swift index 2ade8e565..c183163d9 100644 --- a/PIA VPN/Tiles/SubscriptionTileCollectionViewCell.swift +++ b/PIA VPN/Tiles/SubscriptionTileCollectionViewCell.swift @@ -64,11 +64,11 @@ class SubscriptionTileCollectionViewCell: UICollectionViewCell, TileableCell { if Client.providers.tileProvider.visibleTiles.contains(tileType) { accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Visible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Visible.Tile.action } else { accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Invisible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Invisible.Tile.action } } diff --git a/PIA VPN/Tiles/UsageTile.swift b/PIA VPN/Tiles/UsageTile.swift index 8efe0d41c..49244f205 100644 --- a/PIA VPN/Tiles/UsageTile.swift +++ b/PIA VPN/Tiles/UsageTile.swift @@ -23,6 +23,7 @@ import Foundation import PIALibrary +import UIKit class UsageTile: UIView, Tileable { @@ -58,9 +59,9 @@ class UsageTile: UIView, Tileable { nc.addObserver(self, selector: #selector(displayUsageInformation), name: .PIAVPNUsageUpdate, object: nil) viewShouldRestyle() - self.usageTitle.text = L10n.Tiles.Usage.title.uppercased() - self.uploadTitle.text = L10n.Tiles.Usage.upload - self.downloadTitle.text = L10n.Tiles.Usage.download + self.usageTitle.text = L10n.Localizable.Tiles.Usage.title.uppercased() + self.uploadTitle.text = L10n.Localizable.Tiles.Usage.upload + self.downloadTitle.text = L10n.Localizable.Tiles.Usage.download displayUsageInformation() } @@ -101,9 +102,9 @@ class UsageTile: UIView, Tileable { countStyle: .file) self.uploadValue.alpha = 0.2 self.downloadValue.alpha = 0.2 - self.usageTitle.text = L10n.Tiles.Usage.Ipsec.title + self.usageTitle.text = L10n.Localizable.Tiles.Usage.Ipsec.title } else { - self.usageTitle.text = L10n.Tiles.Usage.title.uppercased() + self.usageTitle.text = L10n.Localizable.Tiles.Usage.title.uppercased() self.uploadValue.alpha = 1 self.downloadValue.alpha = 1 } diff --git a/PIA VPN/Tiles/UsageTileCollectionViewCell.swift b/PIA VPN/Tiles/UsageTileCollectionViewCell.swift index 6edce932b..f6d2b157b 100644 --- a/PIA VPN/Tiles/UsageTileCollectionViewCell.swift +++ b/PIA VPN/Tiles/UsageTileCollectionViewCell.swift @@ -64,11 +64,11 @@ class UsageTileCollectionViewCell: UICollectionViewCell, TileableCell { if Client.providers.tileProvider.visibleTiles.contains(tileType) { accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Visible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Visible.Tile.action } else { accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .normal) accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .highlighted) - accessoryButtonLeft.accessibilityLabel = L10n.Tiles.Accessibility.Invisible.Tile.action + accessoryButtonLeft.accessibilityLabel = L10n.Localizable.Tiles.Accessibility.Invisible.Tile.action } } diff --git a/PIA VPN/TrustedNetworksViewController.swift b/PIA VPN/TrustedNetworksViewController.swift index 18376fbee..252ccf87e 100644 --- a/PIA VPN/TrustedNetworksViewController.swift +++ b/PIA VPN/TrustedNetworksViewController.swift @@ -106,9 +106,9 @@ class TrustedNetworksViewController: AutolayoutViewController { // MARK: Private Methods private func presentKillSwitchAlert() { - let alert = Macros.alert(nil, L10n.Settings.Nmt.Killswitch.disabled) - alert.addCancelAction(L10n.Global.close) - alert.addActionWithTitle(L10n.Global.enable) { + let alert = Macros.alert(nil, L10n.Localizable.Settings.Nmt.Killswitch.disabled) + alert.addCancelAction(L10n.Localizable.Global.close) + alert.addActionWithTitle(L10n.Localizable.Global.enable) { let preferences = Client.preferences.editable() preferences.isPersistentConnection = true preferences.commit() @@ -217,7 +217,7 @@ extension TrustedNetworksViewController: UICollectionViewDelegateFlowLayout, UIC case UICollectionView.elementKindSectionHeader: let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: Cells.header, for: indexPath) as! PIAHeaderCollectionViewCell - headerView.setup(withTitle: L10n.Network.Management.Tool.title, andSubtitle: L10n.Settings.Hotspothelper.description) + headerView.setup(withTitle: L10n.Localizable.Network.Management.Tool.title, andSubtitle: L10n.Localizable.Settings.Hotspothelper.description) return headerView default: diff --git a/PIA VPN/UIDevice+WIFI.swift b/PIA VPN/UIDevice+WIFI.swift new file mode 100644 index 000000000..f02918a22 --- /dev/null +++ b/PIA VPN/UIDevice+WIFI.swift @@ -0,0 +1,24 @@ +// +// UIDevice+WIFI.swift +// PIA VPN +// +// Created by Said Rehouni on 7/11/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import SystemConfiguration +import NetworkExtension +import UIKit + +extension UIDevice { + var WiFiSSID: String? { + guard let interfaces = NEHotspotHelper.supportedNetworkInterfaces(), + interfaces.count > 0, + let interface = interfaces[0] as? NEHotspotNetwork, + !interface.ssid.isEmpty else { + return nil + } + return interface.ssid + } +} diff --git a/PIA VPN/UIViewLoading.swift b/PIA VPN/UIViewLoading.swift new file mode 100644 index 000000000..4fe18d27f --- /dev/null +++ b/PIA VPN/UIViewLoading.swift @@ -0,0 +1,117 @@ +// +// UIViewLoading.swift +// PIALibrary-iOS +// +// Created by Jose Antonio Blaya Garcia on 04/12/2018. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import Foundation +import Lottie +import UIKit + +extension UIView: AnimatingLoadingDelegate { + + private struct LottieRepos { + static var graphLoad: AnimationView? + } + + var graphLoad: AnimationView? { + get { + return objc_getAssociatedObject(self, &LottieRepos.graphLoad) as? AnimationView + } + set { + if let unwrappedValue = newValue { + objc_setAssociatedObject(self, &LottieRepos.graphLoad, unwrappedValue as AnimationView?, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + } + + public func showLoadingAnimation() { + if graphLoad == nil { + graphLoad = AnimationView(name: "pia-spinner") + } + addLoadingAnimation() + } + + private func addLoadingAnimation() { + graphLoad?.loopMode = .loop + if let graphLoad = graphLoad { + self.addSubview(graphLoad) + graphLoad.play() + } + setLoadingConstraints() + } + + public func hideLoadingAnimation() { + graphLoad?.stop() + graphLoad?.removeFromSuperview() + } + + public func adjustLottieSize() { + let lottieWidth = self.frame.width/2 + graphLoad?.frame = CGRect( + x: lottieWidth/2, + y: (self.frame.height - lottieWidth)/2, + width: lottieWidth, + height: lottieWidth + ) + } + + private func setLoadingConstraints() { + if let graphLoad = graphLoad { + + graphLoad.translatesAutoresizingMaskIntoConstraints = false + + NSLayoutConstraint(item: graphLoad, + attribute: .centerX, + relatedBy: .equal, + toItem: self, + attribute: .centerX, + multiplier: 1.0, + constant: 0.0).isActive = true + + NSLayoutConstraint(item: graphLoad, + attribute: .centerY, + relatedBy: .equal, + toItem: self, + attribute: .centerY, + multiplier: 1.0, + constant: 0.0).isActive = true + + let lottieWidth = self.frame.width/2 + + NSLayoutConstraint(item: graphLoad, + attribute: .width, + relatedBy: .equal, + toItem: nil, + attribute: .width, + multiplier: 1.0, + constant: lottieWidth).isActive = true + + NSLayoutConstraint(item: graphLoad, + attribute: .height, + relatedBy: .equal, + toItem: nil, + attribute: .height, + multiplier: 1.0, + constant: lottieWidth).isActive = true + + } + } + +} diff --git a/PIA VPN/UserSurveyManager.swift b/PIA VPN/UserSurveyManager.swift new file mode 100644 index 000000000..bcbdbf6a8 --- /dev/null +++ b/PIA VPN/UserSurveyManager.swift @@ -0,0 +1,48 @@ +// +// UserSurveyManager.swift +// PIA VPN +// +// Created by Waleed Mahmood on 11.02.22. +// Copyright © 2022 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import PIALibrary + +class UserSurveyManager { + static let shared = UserSurveyManager() + + private init() { + let nc = NotificationCenter.default + nc.addObserver(self, selector: #selector(setupConnectionCounters), name: .PIAAccountDidRefresh, object: nil) + + setupConnectionCounters() + } + + deinit { + NotificationCenter.default.removeObserver(self) + } + + @objc private func setupConnectionCounters() { + let appPreferences = AppPreferences.shared + if let _ = appPreferences.successConnectionsUntilSurvey { + return + } + appPreferences.successConnectionsUntilSurvey = appPreferences.successConnections + AppConstants.Survey.numberOfConnectionsUntilPrompt + } + + func handleConnectionSuccess() { + if UserSurveyManager.shouldShowSurveyMessage() { + MessagesManager.shared.showInAppSurveyMessage() + } + } + + // MARK: Survey Settings + static func shouldShowSurveyMessage() -> Bool { + let appPreferences = AppPreferences.shared + guard let successConnectionUntilSurvey = appPreferences.successConnectionsUntilSurvey else { + return false + } + return !appPreferences.userInteractedWithSurvey && appPreferences.successConnections >= successConnectionUntilSurvey + } +} diff --git a/PIA VPN/VPNPermissionViewController.swift b/PIA VPN/VPNPermissionViewController.swift index 4e805a78a..7bcbe2353 100644 --- a/PIA VPN/VPNPermissionViewController.swift +++ b/PIA VPN/VPNPermissionViewController.swift @@ -44,13 +44,14 @@ class VPNPermissionViewController: AutolayoutViewController { override func viewDidLoad() { super.viewDidLoad() - title = L10n.VpnPermission.title + title = L10n.Localizable.VpnPermission.title navigationItem.hidesBackButton = true + self.view.accessibilityIdentifier = AccessibilityId.VPNPermission.screen - imvPicture.image = Asset.imageVpnAllow.image - labelTitle.text = L10n.VpnPermission.Body.title - labelMessage.text = L10n.VpnPermission.Body.subtitle(L10n.Global.ok) - labelFooter.text = L10n.VpnPermission.Body.footer + imvPicture.image = Asset.Images.imageVpnAllow.image + labelTitle.text = L10n.Localizable.VpnPermission.Body.title + labelMessage.text = L10n.Localizable.VpnPermission.Body.subtitle(L10n.Localizable.Global.ok) + labelFooter.text = L10n.Localizable.VpnPermission.Body.footer styleSubmitButton() } @@ -73,17 +74,17 @@ class VPNPermissionViewController: AutolayoutViewController { } private func alertRequiredPermission() { - var message = L10n.VpnPermission.Disallow.Message.basic + var message = L10n.Localizable.VpnPermission.Disallow.Message.basic if MFMailComposeViewController.canSendMail() { - message += "\n" + L10n.VpnPermission.Disallow.Message.support + message += "\n" + L10n.Localizable.VpnPermission.Disallow.Message.support } - let alert = Macros.alert(L10n.VpnPermission.title, message) + let alert = Macros.alert(L10n.Localizable.VpnPermission.title, message) if MFMailComposeViewController.canSendMail() { - alert.addActionWithTitle(L10n.VpnPermission.Disallow.contact) { + alert.addActionWithTitle(L10n.Localizable.VpnPermission.Disallow.contact) { self.contactCustomerSupport() } } - alert.addCancelActionWithTitle(L10n.Global.ok) { + alert.addCancelActionWithTitle(L10n.Localizable.Global.ok) { self.submit() } present(alert, animated: true, completion: nil) @@ -110,8 +111,9 @@ class VPNPermissionViewController: AutolayoutViewController { private func styleSubmitButton() { buttonSubmit.setRounded() buttonSubmit.style(style: TextStyle.Buttons.piaGreenButton) - buttonSubmit.setTitle(L10n.Global.ok.uppercased(), + buttonSubmit.setTitle(L10n.Localizable.Global.ok.uppercased(), for: []) + buttonSubmit.accessibilityIdentifier = AccessibilityId.VPNPermission.submit } } diff --git a/PIA VPN/WalkthroughPageView.swift b/PIA VPN/WalkthroughPageView.swift new file mode 100644 index 000000000..14680868d --- /dev/null +++ b/PIA VPN/WalkthroughPageView.swift @@ -0,0 +1,109 @@ +// +// WalkthroughPageView.swift +// PIA VPN +// +// Created by Davide De Rosa on 12/8/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import PIALibrary +import DeviceCheck + +class WalkthroughPageView: UIView { + struct PageData { + let title: String + + let detail: String + + let image: UIImage? + } + + private let data: PageData + + private(set) var labelTitle = UILabel() + private(set) var labelDetail = UILabel() + + required init?(coder aDecoder: NSCoder) { + data = PageData(title: "", detail: "", image: nil) + super.init(coder: aDecoder) + } + + init(data: PageData) { + self.data = data + super.init(frame: .zero) + + configure() + } + + private func configure() { + let imvImage = UIImageView() + + addSubview(imvImage) + addSubview(labelTitle) + addSubview(labelDetail) + + translatesAutoresizingMaskIntoConstraints = false + imvImage.translatesAutoresizingMaskIntoConstraints = false + labelTitle.translatesAutoresizingMaskIntoConstraints = false + labelDetail.translatesAutoresizingMaskIntoConstraints = false + + var imageMultiplier: CGFloat = 0.55 + var labelSpaceMargin: CGFloat = 5.0 + var textTopMargin: CGFloat = 19.0 + + switch UIDevice().type { + case .iPhoneSE, .iPhone5, .iPhone5S: + imageMultiplier = 0.40 + labelSpaceMargin = 2.0 + textTopMargin = 5.0 + default: break + } + + NSLayoutConstraint.activate([ + imvImage.topAnchor.constraint(equalTo: topAnchor), + imvImage.widthAnchor.constraint(lessThanOrEqualTo: widthAnchor, multiplier: imageMultiplier), + imvImage.centerXAnchor.constraint(equalTo: centerXAnchor), + labelTitle.topAnchor.constraint(equalTo: imvImage.bottomAnchor, constant: textTopMargin), + labelTitle.leftAnchor.constraint(equalTo: leftAnchor, constant: 40.0), + labelTitle.rightAnchor.constraint(equalTo: rightAnchor, constant: -40.0), + labelDetail.topAnchor.constraint(equalTo: labelTitle.bottomAnchor, constant: labelSpaceMargin), + labelDetail.leftAnchor.constraint(equalTo: labelTitle.leftAnchor), + labelDetail.rightAnchor.constraint(equalTo: labelTitle.rightAnchor), + labelDetail.bottomAnchor.constraint(equalTo: bottomAnchor) + ]) + + imvImage.contentMode = .scaleAspectFit + imvImage.setContentCompressionResistancePriority(.defaultLow, for: .vertical) + labelTitle.numberOfLines = 0 + labelDetail.numberOfLines = 0 + + labelTitle.text = data.title + labelDetail.text = data.detail + imvImage.image = data.image + + labelTitle.textAlignment = .center + labelDetail.textAlignment = .center + + } + + func applyStyles() { + Theme.current.applySubtitle(labelDetail) + Theme.current.applyTitle(labelTitle, appearance: .dark) + } + +} diff --git a/PIA VPN/WelcomePageViewController.swift b/PIA VPN/WelcomePageViewController.swift new file mode 100644 index 000000000..fac49bf46 --- /dev/null +++ b/PIA VPN/WelcomePageViewController.swift @@ -0,0 +1,159 @@ +// +// WelcomePageViewController.swift +// PIALibrary-iOS +// +// Created by Davide De Rosa on 10/19/17. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// The Private Internet Access iOS Client is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any later version. +// +// The Private Internet Access iOS Client is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with the Private +// Internet Access iOS Client. If not, see . +// + +import UIKit +import PIALibrary + +class WelcomePageViewController: UIPageViewController { + private var source = [UIViewController]() + + var preset: Preset? + + var selectedPlanIndex: Int? + + var allPlans: [PurchasePlan]? + + weak var completionDelegate: WelcomeCompletionDelegate? + + override func viewDidLoad() { + super.viewDidLoad() + + guard let preset = self.preset else { + fatalError("Preset not propagated") + } + if preset.pages.contains(.login) { + let vc = StoryboardScene.Welcome.loginViewController.instantiate() + source.append(vc) + } + if preset.pages.contains(.purchase) { + let vc = StoryboardScene.Welcome.purchaseViewController.instantiate() + source.append(vc) + } + if preset.pages.contains(.restore) { + let vc = StoryboardScene.Welcome.restoreSignupViewController.instantiate() + source.append(vc) + } + dataSource = self + + guard !source.isEmpty else { + fatalError("Source controllers are empty") + } + let isSinglePage = (source.count == 1) + guard isSinglePage || (preset.pages == .all) else { + fatalError("Currently supports all pages or a single page, not a subset") + } + + for vc in source { + guard let child = vc as? WelcomeChild else { + fatalError("Source element must be a WelcomeChild") + } + child.preset = preset + child.omitsSiblingLink = !isSinglePage + child.completionDelegate = completionDelegate + } + + setViewControllers([source.first!], direction: .forward, animated: false, completion: nil) + + if let scrollView = self.view.subviews.filter({ + $0.isKind(of: UIScrollView.self) + }).first as? UIScrollView { + scrollView.isScrollEnabled = false + } + + } + + func show(page: Pages) { + + // XXX: quick temp solution for log2 + let index: Int + switch page { + case .login: + index = 0 + + case .purchase: + index = 1 + + case .restore: + index = 3 + + default: + return + } + + guard (index < source.count) else { + fatalError("Page \(index) beyond source controllers (\(source.count))") + } + guard let currentIndex = source.index(of: viewControllers!.first!) else { + fatalError("No page displayed yet") + } + let controller = source[index] + let direction: UIPageViewController.NavigationDirection = (index > currentIndex) ? .forward : .reverse + setViewControllers([controller], direction: direction, animated: true, completion: nil) + } + + // MARK: Unwind + + @IBAction private func unwoundSignupFailure(segue: UIStoryboardSegue) { + } + + // MARK: Size classes + + public override func overrideTraitCollection(forChild childViewController: UIViewController) -> UITraitCollection? { + guard let window = view.window else { + return super.traitCollection + } + let isLandscape = (window.bounds.size.width > window.bounds.size.height) + let minHeight: CGFloat + if let _ = childViewController as? LoginViewController { + minHeight = 568.0 + } else { + minHeight = 667.0 + } + if !Macros.isDevicePad && (isLandscape || (window.bounds.size.height < minHeight)) { + return UITraitCollection(verticalSizeClass: .compact) + } else { + return UITraitCollection(verticalSizeClass: .regular) + } + } +} + +extension WelcomePageViewController: UIPageViewControllerDataSource { + func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { + guard let index = source.index(of: viewController) else { + fatalError("Cannot find view controller") + } + if (index == 0) { + return nil + } + return source[index - 1] + } + + func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { + guard let index = source.index(of: viewController) else { + fatalError("Cannot find view controller") + } + if (index == source.count - 1) { + return nil + } + return source[index + 1] + } +} diff --git a/PIA VPN/WifiNetworkMonitor.swift b/PIA VPN/WifiNetworkMonitor.swift new file mode 100644 index 000000000..8a96c9b64 --- /dev/null +++ b/PIA VPN/WifiNetworkMonitor.swift @@ -0,0 +1,69 @@ +// +// WifiNetworkMonitor.swift +// PIA VPN +// +// Created by Said Rehouni on 11/8/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import Network +import NetworkExtension + +class WifiNetworkMonitor: NetworkMonitor { + + private func getWifiAndEthernetIpAddress() -> [IPv4Address] { + var addresses = [IPv4Address]() + // Get list of all interfaces + var ifaddr: UnsafeMutablePointer? + defer { + freeifaddrs(ifaddr) + } + guard getifaddrs(&ifaddr) == 0, let firstAddr = ifaddr else { + return [] + } + + // Loop every interface, retrieve IPAddress and interface name (en0, en1, tun1) + for ptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) { + let flags = Int32(ptr.pointee.ifa_flags) + // Find all active ifaddrs and avoid loopback interface. + if (flags & (IFF_UP | IFF_RUNNING | IFF_LOOPBACK)) == (IFF_UP | IFF_RUNNING) { + let addr = ptr.pointee.ifa_addr.pointee + if addr.sa_family == UInt8(AF_INET) { + // Convert interface address to a human readable string: + var ipAddressStr = [CChar](repeating: 0, count: Int(NI_MAXHOST)) + let nameInfo = getnameinfo( + ptr.pointee.ifa_addr, + socklen_t(addr.sa_len), + &ipAddressStr, + socklen_t(ipAddressStr.count), + nil, + socklen_t(0), + NI_NUMERICHOST + ) + if nameInfo == 0, + let ipAddress = IPv4Address(.init(cString: ipAddressStr)) + { + let interfaceName = String(cString: ptr.pointee.ifa_name) + if ipAddress.isLinkLocal == false && interfaceName.starts(with: "en") { + addresses.append(ipAddress) + } + } + } + } + } + return addresses + } + + func checkForRFC1918Vulnerability() -> Bool { + let wifiIPAddresses = getWifiAndEthernetIpAddress() + return wifiIPAddresses.contains(where: { $0.isRFC1918Compliant == false }) + } + + func isConnected() -> Bool { + if let currentNetworks = NEHotspotHelper.supportedNetworkInterfaces() { + return currentNetworks.contains(where: { $0 is NEHotspotNetwork }) + } + return false + } +} diff --git a/PIA VPN/ar.lproj/Localizable.strings b/PIA VPN/ar.lproj/Localizable.strings index 29f7826f7..f5d0448f2 100644 --- a/PIA VPN/ar.lproj/Localizable.strings +++ b/PIA VPN/ar.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "تجديد"; "expiration.message" = "سينتهي اشتراكك قريبًا. قم بتجديده لتبقى محميًا."; +"local_notification.non_compliant_wifi.title" = "واي فاي غير آمنة: %@"; +"local_notification.non_compliant_wifi.text" = "اضغط هنا لحماية جهازك"; + // SHORTCUTS "shortcuts.connect" = "اتصال"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "خطة شهرية"; "account.subscriptions.trial" = "خطة تجريبية"; "account.unauthorized" = "حدث خطأ. يرجى محاولة تسجيل الدخول مرة أخرى"; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "حذف الحساب"; +"account.delete.alert.title" = "هل أنت متأكد؟"; +"account.delete.alert.message" = "يعد حذف حساب PIA الخاص بك نهائي ولا رجعة فيه. لن تتمكن من استرجاع بيانات اعتماد PIA الخاصة بك بعد تنفيذ هذا الإجراء. يرجى الملاحظة بأن هذا الإجراء يعني حذف حسابك من قاعدة بياناتنا فقط، ولا يعني حذف اشتراكك. ستحتاج إلى زيارة حساب Apple الخاص بك وحذف اشتراك Private Internet Access الخاص بك من هناك. خلافاً لذلك، ستستمر في دفع رسوم الاشتراك رغم أن حسابك لن يكون نشطاً."; +"account.delete.alert.failureMessage" = "حدث خطأ أثناء حذف حسابك. يرجى المحاولة مرة أخرى."; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "النسق النشط"; "settings.application_settings.kill_switch.title" = "مفتاح إيقاف VPN"; "settings.application_settings.kill_switch.footer" = "يؤدي استخدام مفتاح إيقاف VPN إلى تعطيل اتصالك بالإنترنت إذا كان الـ VPN في وضع إعادة الاتصال. لا ينطبق ذلك ذلك على الاتصال اليدوي."; +"settings.application_settings.leak_protection.title" = "حماية من تسريب المعلومات"; +"settings.application_settings.leak_protection.footer" = "يتضمن نظام iOS ميزات مصممة للعمل خارج شبكة VPN افتراضيًا مثل AirDrop و CarPlay و AirPlay ونقاط الاتصال الشخصية. يؤدي تمكين الحماية المخصصة من تسريب المعلومات إلى توجيه حركة البيانات عبر VPN ولكنه قد يؤثر على كيفية عمل هذه الميزات. المزيد من المعلومات"; +"settings.application_settings.leak_protection.more_info" = "المزيد من المعلومات"; +"settings.application_settings.allow_local_network.title" = "السماح بالوصول إلى الأجهزة الموجودة على الشبكة المحلية"; +"settings.application_settings.allow_local_network.footer" = "كن متصلًا بالأجهزة المحلية مثل الطابعات أو خوادم الملفات أثناء الاتصال بشبكة VPN. (اسمح بذلك فقط إذا كنت تثق في الأشخاص المتصلين بشبكتك والأجهزة التي عليها.)"; "settings.application_settings.mace.title" = "™PIA MACE"; "settings.application_settings.mace.footer" = "يحجب ™PIA MACE الإعلانات والمتعقبين والبرمجيات الضارة عندما تكون متصلًا بخدمة VPN."; +"settings.application_settings.leak_protection.alert.title" = "سيتم تفعيل التعديلات على إعدادات الـ VPN عند معاودة الاتصال"; "settings.content_blocker.title" = "حالة حظر المحتوى في Safari"; "settings.content_blocker.state.title" = "الحالة الحالية"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "زر اتصال VPN. خدمة VPN متصلة حاليًا"; "dashboard.accessibility.vpn.button.isOff" = "زر اتصال VPN. خدمة VPN غير متصلة حاليًا"; +"dashboard.vpn.leakprotection.alert.title" = "تم العثور على شبكة واي فاي غير آمنة"; +"dashboard.vpn.leakprotection.alert.message" = "لمنع تسريب البيانات، اضغط على تعطيل الآن لإغلاق \"السماح بالوصول إلى الأجهزة الموجودة على الشبكة المحلية\" وإعادة الاتصال تلقائيًا."; +"dashboard.vpn.leakprotection.alert.cta1" = "تعطيل الآن"; +"dashboard.vpn.leakprotection.alert.cta2" = "اعرف أكثر"; +"dashboard.vpn.leakprotection.alert.cta3" = "تجاهل"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "لمنع تسرب البيانات، اضغط على التبديل الآن للتغير إلى بروتوكول IKEv2 VPN وإعادة الاتصال تلقائيًا."; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "التبديل الآن"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "نأمل أن يلبي منتجنا لشبكات VPN توقعاتك"; "rating.problems.question" = "ما الخلل الذي حصل؟"; "rating.problems.subtitle" = "هل لديك أي ملاحظات؟ يمكننا مساعدتك على تحسين تجربتك في استخدام PIA"; -"rating.rate.question" = "ما رأيك بترك مراجعة في AppStore؟"; +"rating.review.question" = "ما رأيك بترك مراجعة في AppStore؟"; +"rating.rate.question" = "ماذا عن ترك تقييم في App Store؟"; "rating.rate.subtitle" = "نقدّر لك مشاركة تجربتك"; "rating.error.question" = "تعذّر تأسيس اتصال"; "rating.error.subtitle" = "يمكنك محاولة تحديد منطقة مختلفة أو إعلامنا بها عن طريق فتح تذكرة دعم."; "rating.error.button.send" = "إرسال ملاحظات"; +"rating.alert.button.notreally" = "لا أرغب"; +"rating.alert.button.nothanks" = "لا، شكرًا."; +"rating.alert.button.oksure" = "بالتأكيد"; // CALLING CARDS "card.wireguard.title" = "جرّب ®WireGuard اليوم!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "تم تنشيط عنوان IP المخصّص بنجاح. سيكون متاحًا في قائمة اختيار المنطقة."; "dedicated.ip.message.expired.token" = "انتهت صلاحية الرمز. يرجى إنشاء رمز جديد من صفحة حسابك على الموقع الإلكتروني."; "dedicated.ip.message.error.token" = "انتهت صلاحية الرمز. يرجى إنشاء رمز جديد من صفحة حسابك على الموقع الإلكتروني."; +"dedicated.ip.message.error.retryafter" = "عدد طلبات تفعيل التوكن كبير جداً. يرجى إعادة المحاولة بعد %@ ثانية."; "dedicated.ip.message.token.willexpire" = "ستنتهي صلاحية عنوان IP المخصّص قريبًا. احصل على واحد جديد"; "dedicated.ip.message.token.willexpire.link" = "احصل على واحد جديد"; "dedicated.ip.message.ip.updated" = "تم تحديث عنوان IP المخصّص"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "إظهار رسائل اتصال الخدمة"; "inapp.messages.settings.updated" = "تم تحديث الإعدادات"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "المنطقة"; +"widget.liveActivity.protocol.title" = "البروتوكول"; diff --git a/PIA VPN/da.lproj/Localizable.strings b/PIA VPN/da.lproj/Localizable.strings index 5190ecf99..da4073046 100644 --- a/PIA VPN/da.lproj/Localizable.strings +++ b/PIA VPN/da.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "Fornyelse"; "expiration.message" = "Dit abonnement udløber snart. Forny for at forblive beskyttet."; +"local_notification.non_compliant_wifi.title" = "Usikret wi-fi: %@"; +"local_notification.non_compliant_wifi.text" = "Tryk her for at sikre din enhed"; + // SHORTCUTS "shortcuts.connect" = "Forbind"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "Månedsabonnement"; "account.subscriptions.trial" = "Prøveabonnement"; "account.unauthorized" = "Noget gik galt. Prøv at logge på igen."; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "Slet konto"; +"account.delete.alert.title" = "Er du sikker?"; +"account.delete.alert.message" = "Hvis du sletter din PIA-konto, er det permanent og uigenkaldeligt. Du vil ikke kunne gendanne dine PIA-legitimationsoplysninger, når du har udført denne handling. Bemærk, at denne handling kun sletter din PIA-konto fra vores database, men IKKE sletter dit aabonnement. Du er nødt til at gå til din Apple-konto og annullere dit Private Internet Access-abonnement derfra. Ellers vil du fortsat blive faktureret, også selv om din PIA-konto ikke længere er aktiv."; +"account.delete.alert.failureMessage" = "Noget gik galt, da du slettede din konto, prøv igen senere."; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "Aktivt tema"; "settings.application_settings.kill_switch.title" = "VPN-afbryderknap"; "settings.application_settings.kill_switch.footer" = "VPN-kill switchen forebygger kontakt til internettet, hvis VPN-forbindelsen genoprettes. Dette udelukker manuel frakobling."; +"settings.application_settings.leak_protection.title" = "Lækagebeskyttelse"; +"settings.application_settings.leak_protection.footer" = "iOS inkluderer funktioner designet til at fungere uden for VPN'et som standard, såsom AirDrop, CarPlay, AirPlay og personlige hotspots. Aktivering af tilpasset lækagebeskyttelse dirigerer denne trafik gennem VPN'et, men kan påvirke, hvordan disse funktioner fungerer. Mere info"; +"settings.application_settings.leak_protection.more_info" = "Mere info"; +"settings.application_settings.allow_local_network.title" = "Tillad adgang til enheder på det lokale netværk"; +"settings.application_settings.allow_local_network.footer" = "Hold forbindelsen til lokale enheder såsom printere eller filservere, mens du er tilsluttet til VPN'et. (Tillad kun dette, hvis du har tillid til personerne og enhederne på dit netværk.)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™ blokerer annoncer, trackers og malware, mens du har forbindelse til VPN."; +"settings.application_settings.leak_protection.alert.title" = "Ændringer af VPN-indstillingerne træder i kraft ved næste forbindelse"; "settings.content_blocker.title" = "Safari Indholdsblokeringstilstand"; "settings.content_blocker.state.title" = "Aktuel status"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "VPN-forbindelse-knap. VPN er i øjeblikket forbundet"; "dashboard.accessibility.vpn.button.isOff" = "VPN-forbindelse-knap. VPN er i øjeblikket afbrudt"; +"dashboard.vpn.leakprotection.alert.title" = "Usikret wi-fi registreret"; +"dashboard.vpn.leakprotection.alert.message" = "For at forhindre datalækage skal du trykke på Deaktiver nu for at deaktivere \"Tillad adgang til enheder på det lokale netværk\" og automatisk oprette forbindelse igen."; +"dashboard.vpn.leakprotection.alert.cta1" = "Deaktiver nu"; +"dashboard.vpn.leakprotection.alert.cta2" = "Få flere oplysninger"; +"dashboard.vpn.leakprotection.alert.cta3" = "Ignorer"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "For at forhindre datalækage skal du trykke på Skift nu for at skifte til IKEv2 VPN-protokollen og automatisk oprette forbindelse igen."; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "Skift nu"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "Vi håber, at vores VPN lever op til dine forventninger."; "rating.problems.question" = "Hvad gik galt?"; "rating.problems.subtitle" = "Vil du give noget feedback? Vi kan hjælpe dig med at forbedre din oplevelse med PIA"; -"rating.rate.question" = "Hvad med en AppStore-anmeldelse?"; +"rating.review.question" = "Hvad med en AppStore-anmeldelse?"; +"rating.rate.question" = "Hvad med en vurdering i AppStore?"; "rating.rate.subtitle" = "Vi sætter pris på, at du deler din oplevelse"; "rating.error.question" = "Forbindelsen kunne ikke oprettes"; "rating.error.subtitle" = "Du kan prøve at vælge en anden region, eller fortælle os om det, ved at åbne en supportbillet."; "rating.error.button.send" = "Send feedback"; +"rating.alert.button.notreally" = "Nej, helst ikke"; +"rating.alert.button.nothanks" = "Nej tak."; +"rating.alert.button.oksure" = "OK, selvfølgelig!"; // CALLING CARDS "card.wireguard.title" = "Prøv WireGuard® i dag!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "Din dedikerede IP er blevet aktiveret. Den vil være tilgængelig på din liste over Valg af regioner."; "dedicated.ip.message.expired.token" = "Dit token er udløbet. Generer et nyt fra din kontoside på websiden."; "dedicated.ip.message.error.token" = "Dit token er udløbet. Generer et nyt fra din kontoside på websiden."; +"dedicated.ip.message.error.retryafter" = "For mange mislykkede anmodninger om aktivering af token. Prøv igen efter %@ sekund(er)."; "dedicated.ip.message.token.willexpire" = "Din dedikerede IP udløber snart. Få en ny"; "dedicated.ip.message.token.willexpire.link" = "Få en ny"; "dedicated.ip.message.ip.updated" = "Din dedikerede IP blev opdateret"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "Vis servicekommunikationsmeddelelser"; "inapp.messages.settings.updated" = "Indstillinger er blevet opdateret"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "Region"; +"widget.liveActivity.protocol.title" = "Protokol"; diff --git a/PIA VPN/de.lproj/Localizable.strings b/PIA VPN/de.lproj/Localizable.strings index a97ddde8f..e5ec3a0d7 100644 --- a/PIA VPN/de.lproj/Localizable.strings +++ b/PIA VPN/de.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "Verlängerung"; "expiration.message" = "Dein Abonnement endet bald. Verlängere deinen Schutz."; +"local_notification.non_compliant_wifi.title" = "Ungesichertes WLAN: %@"; +"local_notification.non_compliant_wifi.text" = "Tippe hier, um dein Gerät zu schützen"; + // SHORTCUTS "shortcuts.connect" = "Verbinden"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "Monatsabo"; "account.subscriptions.trial" = "Testversion"; "account.unauthorized" = "Etwas ging schief. Bitte versuchen, erneut anzumelden"; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "Konto löschen"; +"account.delete.alert.title" = "Sind Sie sicher?"; +"account.delete.alert.message" = "Die Löschung Ihres PIA-Kontos ist dauerhaft und unwiderruflich. Sie können Ihre PIA-Anmeldedaten nach dieser Aktion nicht wiederherstellen. Bitte beachten Sie, dass diese Aktion nur Ihr PIA-Konto aus unserer Datenbank löscht, aber NICHT Ihr Abonnement. Sie müssen zu Ihrem Apple-Konto gehen und das Private Internet Access-Abonnement von dort aus kündigen. Anderenfalls werden Sie weiterhin belastet, auch wenn Ihr PIA-Konto nicht mehr aktiv ist."; +"account.delete.alert.failureMessage" = "Etwas schlug beim Löschen Ihres Kontos fehl. Versuchen Sie es bitte später noch einmal."; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "Aktives Theme"; "settings.application_settings.kill_switch.title" = "VPN-Killswitch"; "settings.application_settings.kill_switch.footer" = "Der VPN-Notausschalter unterbricht den Internetzugang, wenn die VPN-Verbindung neu aufgebaut wird. Dies schließt manuelles Trennen aus."; +"settings.application_settings.leak_protection.title" = "Schutz vor Datenlecks"; +"settings.application_settings.leak_protection.footer" = "iOS enthält Funktionen, die standardmäßig außerhalb des VPNs funktionieren, wie AirDrop, CarPlay, AirPlay und „Persönliche Hotspots“. Die Aktivierung des benutzerdefinierten Schutzes vor Datenlecks leitet diesen Datenverkehr durch das VPN, kann aber die Funktionsweise dieser Funktionen beeinträchtigen. Weitere Informationen"; +"settings.application_settings.leak_protection.more_info" = "Weitere Informationen"; +"settings.application_settings.allow_local_network.title" = "Zugriff auf Geräte im lokalen Netzwerk erlauben"; +"settings.application_settings.allow_local_network.footer" = "Die Verbindung zu lokalen Geräten wie Druckern oder Dateiservern während einer Verbindung zum VPN halten. (Erlaube dies nur, wenn du den Personen und Geräten in deinem Netzwerk vertraust.)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™ blockiert Werbung, Tracker und Malware bei aktiver VPN-Verbindung."; +"settings.application_settings.leak_protection.alert.title" = "Änderungen an den VPN-Einstellungen werden bei der nächsten Verbindung aktiv"; "settings.content_blocker.title" = "Status Inhalts-Blocker für Safari"; "settings.content_blocker.state.title" = "Aktueller Status"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "VPN-Verbindungs-Schaltfläche. VPN derzeit verbunden"; "dashboard.accessibility.vpn.button.isOff" = "VPN-Verbindungs-Schaltfläche. VPN derzeit nicht verbunden"; +"dashboard.vpn.leakprotection.alert.title" = "Ungesichertes WLAN erkannt"; +"dashboard.vpn.leakprotection.alert.message" = "Um Datenlecks zu verhindern, tippe auf „Jetzt deaktivieren“, um „Zugriff auf Geräte im lokalen Netzwerk erlauben“ zu deaktivieren und automatisch erneut eine Verbindung herzustellen."; +"dashboard.vpn.leakprotection.alert.cta1" = "Jetzt deaktivieren"; +"dashboard.vpn.leakprotection.alert.cta2" = "Mehr erfahren"; +"dashboard.vpn.leakprotection.alert.cta3" = "Ignorieren"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "Um Datenlecks zu verhindern, tippe auf „Jetzt wechseln“, um zum IKEv2 VPN-Protokoll zu wechseln und automatisch erneut eine Verbindung herzustellen."; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "Jetzt wechseln"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "Wir hoffen, dass unsere VPN-Lösung Ihre Erwartungen erfüllt."; "rating.problems.question" = "Was ist schiefgelaufen?"; "rating.problems.subtitle" = "Möchten Sie Feedback geben? Wir können Ihnen helfen, Ihre Erfahrungen mit PIA zu verbessern"; -"rating.rate.question" = "Wie wäre es mit einer Bewertung im AppStore?"; +"rating.review.question" = "Wie wäre es mit einer Rezension im App Store?"; +"rating.rate.question" = "Wie wäre es mit einer Bewertung im App Store?"; "rating.rate.subtitle" = "Wir wissen es zu schätzen, dass Sie uns Ihre Erfahrungen mitteilen"; "rating.error.question" = "Die Verbindung konnte nicht hergestellt werden"; "rating.error.subtitle" = "Sie können versuchen, eine andere Region auszuwählen oder uns darüber zu informieren, indem Sie ein Support-Ticket öffnen."; "rating.error.button.send" = "Feedback senden"; +"rating.alert.button.notreally" = "Nicht wirklich"; +"rating.alert.button.nothanks" = "Nein danke."; +"rating.alert.button.oksure" = "Okay, sicher!"; // CALLING CARDS "card.wireguard.title" = "WireGuard® noch heute testen!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "Ihre Dedizierte IP wurde erfolgreich aktiviert. Sie wird in der Auswahlliste Ihrer Region verfügbar sein."; "dedicated.ip.message.expired.token" = "Ihr Token ist abgelaufen. Bitte generieren Sie von Ihrer Konto-Seite auf der Webseite ein neues."; "dedicated.ip.message.error.token" = "Ihr Token ist abgelaufen. Bitte generieren Sie ein neues auf Ihrer Konto-Seite auf der Webseite."; +"dedicated.ip.message.error.retryafter" = "Zu viele fehlgeschlagene Token-Aktivierungsanforderungen. Bitte versuche es nach %@ Sekunde(n) erneut."; "dedicated.ip.message.token.willexpire" = "Ihre dedizierte IP wird bald ablaufen. Eine neue abrufen"; "dedicated.ip.message.token.willexpire.link" = "Eine neue abrufen"; "dedicated.ip.message.ip.updated" = "Ihre dedizierte IP wurde aktualisiert"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "Meldungen der Servicekommunikation anzeigen"; "inapp.messages.settings.updated" = "Die Einstellungen wurden aktualisiert"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "Region"; +"widget.liveActivity.protocol.title" = "Protokoll"; diff --git a/PIA VPN/en.lproj/Localizable.strings b/PIA VPN/en.lproj/Localizable.strings index 66aa92638..489233b1a 100644 --- a/PIA VPN/en.lproj/Localizable.strings +++ b/PIA VPN/en.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "Renewal"; "expiration.message" = "Your subscription expires soon. Renew to stay protected."; +"local_notification.non_compliant_wifi.title" = "Unsecured Wi-Fi: %@"; +"local_notification.non_compliant_wifi.text" = "Tap here to secure your device"; + // SHORTCUTS "shortcuts.connect" = "Connect"; @@ -113,6 +116,8 @@ "account.delete.alert.title" = "Are you sure?"; "account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; "account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "Active theme"; "settings.application_settings.kill_switch.title" = "VPN Kill Switch"; "settings.application_settings.kill_switch.footer" = "The VPN kill switch prevents access to the Internet if the VPN connection is reconnecting. This excludes disconnecting manually."; +"settings.application_settings.leak_protection.title" = "Leak Protection"; +"settings.application_settings.leak_protection.footer" = "iOS includes features designed to operate outside the VPN by default, such as AirDrop, CarPlay, AirPlay, and Personal Hotspots. Enabling custom leak protection routes this traffic through the VPN but may affect how these features function. More info"; +"settings.application_settings.leak_protection.more_info" = "More info"; +"settings.application_settings.allow_local_network.title" = "Allow access to devices on local network"; +"settings.application_settings.allow_local_network.footer" = "Stay connected to local devices like printers or file servers while connected to the VPN. (Allow this only if you trust the people and devices on your network.)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™ blocks ads, trackers, and malware while you're connected to the VPN."; +"settings.application_settings.leak_protection.alert.title" = "Changes to the VPN Settings will take effect on the next connection"; "settings.content_blocker.title" = "Safari Content Blocker state"; "settings.content_blocker.state.title" = "Current state"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "VPN Connection button. The VPN is currently connected"; "dashboard.accessibility.vpn.button.isOff" = "VPN Connection button. The VPN is currently disconnected"; +"dashboard.vpn.leakprotection.alert.title" = "Unsecured Wi-Fi detected"; +"dashboard.vpn.leakprotection.alert.message" = "To prevent data leaks, tap Disable Now to turn off “Allow access to devices on local network\" and automatically reconnect."; +"dashboard.vpn.leakprotection.alert.cta1" = "Disable Now"; +"dashboard.vpn.leakprotection.alert.cta2" = "Learn more"; +"dashboard.vpn.leakprotection.alert.cta3" = "Ignore"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "To prevent data leaks, tap Switch Now to change to the IKEv2 VPN protocol and automatically reconnect."; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "Switch Now"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "We hope our VPN product is meeting your expectations"; "rating.problems.question" = "What went wrong?"; "rating.problems.subtitle" = "Do you want to give feedback? We can help you to improve your experience using PIA"; -"rating.rate.question" = "How about an AppStore review?"; +"rating.review.question" = "How about an AppStore review?"; +"rating.rate.question" = "How about a rating on the AppStore?"; "rating.rate.subtitle" = "We appreciate you sharing your experience"; "rating.error.question" = "The connection couldn't be established"; "rating.error.subtitle" = "You can try selecting a different region or letting us know about it by opening a support ticket."; "rating.error.button.send" = "Send feedback"; +"rating.alert.button.notreally" = "Not Really"; +"rating.alert.button.nothanks" = "No, thanks."; +"rating.alert.button.oksure" = "Ok, sure!"; // CALLING CARDS "card.wireguard.title" = "Try WireGuard® today!"; @@ -410,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "Show Service Communication Messages"; "inapp.messages.settings.updated" = "Settings have been updated"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "Region"; +"widget.liveActivity.protocol.title" = "Protocol"; diff --git a/PIA VPN/es-MX.lproj/Localizable.strings b/PIA VPN/es-MX.lproj/Localizable.strings index 472abb401..3e646e38d 100644 --- a/PIA VPN/es-MX.lproj/Localizable.strings +++ b/PIA VPN/es-MX.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "Renovación"; "expiration.message" = "Tu suscripción expira pronto. Renueva para estar protegido."; +"local_notification.non_compliant_wifi.title" = "Wifi no protegida: %@"; +"local_notification.non_compliant_wifi.text" = "Toca aquí para proteger el dispositivo"; + // SHORTCUTS "shortcuts.connect" = "Conectar"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "Plan mensual"; "account.subscriptions.trial" = "Plan de prueba"; "account.unauthorized" = "Se ha producido un error. Intenta volver a iniciar sesión."; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "Eliminar cuenta"; +"account.delete.alert.title" = "¿Estás seguro?"; +"account.delete.alert.message" = "Eliminar tu cuenta de PIA es permanente e irreversible. Una vez hecho, no podrás recuperar tus credenciales de PIA. Ten en cuenta que esta acción solo elimina tu cuenta de PIA de nuestra base de datos, pero NO cancela tu suscripción. Deberás ir a tu cuenta de Apple y cancelar allí la suscripción a Private Internet Access. De lo contrario, se te seguirá cobrando, aunque la cuenta de PIA ya no estará activa."; +"account.delete.alert.failureMessage" = "Algo ha fallado durante la eliminación de la cuenta. Inténtalo más tarde, por favor."; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "Activar tema"; "settings.application_settings.kill_switch.title" = "Interruptor de corte de VPN"; "settings.application_settings.kill_switch.footer" = "El botón de pánico de VPN evita el acceso a Internet si la conexión VPN se está volviendo a conectar. Esto excluye la desconexión manual."; +"settings.application_settings.leak_protection.title" = "Protección contra filtraciones"; +"settings.application_settings.leak_protection.footer" = "iOS incluye funciones diseñadas para operar fuera de la VPN por omisión, como AirDrop, CarPlay, AirPlay y los puntos de acceso personales. Habilitar la protección personalizada contra las filtraciones dirige este tráfico a través de la VPN, pero puede afectar a su funcionamiento. Más información"; +"settings.application_settings.leak_protection.more_info" = "Más información"; +"settings.application_settings.allow_local_network.title" = "Permitir acceso a dispositivos de la red local"; +"settings.application_settings.allow_local_network.footer" = "Mantente conectado a dispositivos locales como impresoras o servidores de archivos mientras estés conectado a la VPN. (Solo debes permitirlo si confías en las personas y los dispositivos de tu red.)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™ bloquea publicidad, rastreadores y malware mientras estás conectado a la VPN."; +"settings.application_settings.leak_protection.alert.title" = "Los cambios en la configuración de la VPN tendrán efecto en la próxima conexión"; "settings.content_blocker.title" = "Estado del bloqueador de contenido de Safari"; "settings.content_blocker.state.title" = "Estado actual"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "Botón de conexión de VPN. La VPN está conectada en este momento."; "dashboard.accessibility.vpn.button.isOff" = "Botón de conexión de VPN. La VPN está desconectada en este momento."; +"dashboard.vpn.leakprotection.alert.title" = "Detectada red wifi no protegida"; +"dashboard.vpn.leakprotection.alert.message" = "Para evitar filtraciones de datos, toca en \"Desactivar ahora\" para desactivar la opción \"Permitir acceso a dispositivos de la red local\" y restablecer la conexión automáticamente."; +"dashboard.vpn.leakprotection.alert.cta1" = "Desactivar ahora"; +"dashboard.vpn.leakprotection.alert.cta2" = "Más información"; +"dashboard.vpn.leakprotection.alert.cta3" = "Ignorar"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "Para evitar las filtraciones de datos, toca en \"Cambiar ahora\" para cambiar al protocolo VPN IKEv2 y restablecer la conexión automáticamente."; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "Cambiar ahora"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "Esperamos que nuestro producto de VPN cumpla tus expectativas."; "rating.problems.question" = "¿Qué ha salido mal?"; "rating.problems.subtitle" = "¿Quieres darnos tu opinión? Podemos ayudarte a mejorar tu experiencia con PIA."; -"rating.rate.question" = "¿Qué tal si nos valoras en App Store?"; +"rating.review.question" = "¿Quieres escribir una reseña en el App Store?"; +"rating.rate.question" = "¿Quieres dar una puntuación en el App Store?"; "rating.rate.subtitle" = "Te agradecemos que compartas tu experiencia."; "rating.error.question" = "No se pudo establecer la conexión."; "rating.error.subtitle" = "Puedes probar a seleccionar otra región o abrir un ticket de asistencia para comentarnos el problema."; "rating.error.button.send" = "Enviar opinión"; +"rating.alert.button.notreally" = "Realmente no"; +"rating.alert.button.nothanks" = "No, gracias."; +"rating.alert.button.oksure" = "¡Claro que sí!"; // CALLING CARDS "card.wireguard.title" = "¡Prueba WireGuard® hoy!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "Tu IP dedicada se activó correctamente. Estará disponible en tu lista de selección de región."; "dedicated.ip.message.expired.token" = "Tu token caducó. Genera uno nuevo en la página de tu cuenta en el sitio web."; "dedicated.ip.message.error.token" = "Tu token caducó. Genera uno nuevo en la página de tu cuenta en el sitio web."; +"dedicated.ip.message.error.retryafter" = "Demasiadas solicitudes de activación de token fallidas. Vuelve a intentarlo pasados %@ segundo(s)."; "dedicated.ip.message.token.willexpire" = "Tu IP dedicada caducará pronto. Obtén una nueva."; "dedicated.ip.message.token.willexpire.link" = "Obtén una nueva"; "dedicated.ip.message.ip.updated" = "Tu IP dedicada perfil se actualizó."; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "Mostrar mensajes de comunicación de servicio"; "inapp.messages.settings.updated" = "Se actualizaron los ajustes"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "Región"; +"widget.liveActivity.protocol.title" = "Protocolo"; diff --git a/PIA VPN/fr.lproj/Localizable.strings b/PIA VPN/fr.lproj/Localizable.strings index 287bf89b9..b2d8e6082 100644 --- a/PIA VPN/fr.lproj/Localizable.strings +++ b/PIA VPN/fr.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "Renouvellement"; "expiration.message" = "Votre adhésion expire bientôt. Renouvelez pour rester protégé."; +"local_notification.non_compliant_wifi.title" = "Wi-Fi non sécurisé : %@"; +"local_notification.non_compliant_wifi.text" = "Appuyez ici pour sécuriser votre appareil"; + // SHORTCUTS "shortcuts.connect" = "Se connecter"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "Forfait mensuel"; "account.subscriptions.trial" = "Forfait d'essai"; "account.unauthorized" = "Un problème est survenu. Veuillez réessayer de vous connecter"; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "Supprimer le compte"; +"account.delete.alert.title" = "Êtes-vous sûr ?"; +"account.delete.alert.message" = "La suppression de votre compte PIA est permanente et irréversible. Vous ne pourrez plus récupérer vos identifiants PIA après avoir effectué cette opération. Veuillez noter que cette opération supprime uniquement votre compte PIA de notre base de données, mais qu’elle ne supprime PAS votre abonnement. Vous devrez ensuite accéder à votre compte Apple et annuler l’abonnement à Private Internet Access à cet endroit. Vous risquez sinon de continuer à payer, même si votre compte PIA n’est plus actif."; +"account.delete.alert.failureMessage" = "Un problème est survenu lors de la suppression de votre compte. Veuillez réessayer plus tard."; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "Thème actif"; "settings.application_settings.kill_switch.title" = "Killswitch du VPN"; "settings.application_settings.kill_switch.footer" = "Le killswitch du VPN empêche l'accès à Internet si la connexion VPN est en cours de reconnexion. Cela exclut la déconnexion manuelle."; +"settings.application_settings.leak_protection.title" = "Protection contre les fuites de données"; +"settings.application_settings.leak_protection.footer" = "iOS comprend des fonctionnalités conçues pour opérer par défaut en dehors du VPN, comme AirDrop, CarPlay, AirPlay et le partage de connexion. L’activation de la protection personnalisée contre les fuites de données achemine ce trafic à travers le VPN, mais risque de perturber ces fonctionnalités. En savoir plus"; +"settings.application_settings.leak_protection.more_info" = "En savoir plus"; +"settings.application_settings.allow_local_network.title" = "Autoriser l’accès aux appareils sur le réseau local"; +"settings.application_settings.allow_local_network.footer" = "Restez connecté aux appareils locaux tels que les imprimantes ou les serveurs de fichiers tout en étant connecté au VPN. (N’accordez cette autorisation que si vous faites confiance aux personnes et aux appareils de votre réseau.)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™ bloque les publicités, les traqueurs et les logiciels malveillants quand vous êtes connecté au VPN."; +"settings.application_settings.leak_protection.alert.title" = "Les modifications apportées aux réglages VPN prendront effet à la prochaine connexion"; "settings.content_blocker.title" = "État du bloqueur de contenu Safari"; "settings.content_blocker.state.title" = "État actuel"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "Bouton de connexion VPN. Le VPN est actuellement connecté"; "dashboard.accessibility.vpn.button.isOff" = "Bouton de connexion VPN. Le VPN est actuellement déconnecté"; +"dashboard.vpn.leakprotection.alert.title" = "Wi-Fi non sécurisé détecté"; +"dashboard.vpn.leakprotection.alert.message" = "Pour éviter les fuites de données, appuyez sur « Désactiver » afin de désactiver l’option « Autoriser l’accès aux appareils sur le réseau local » et permettre la reconnexion automatique."; +"dashboard.vpn.leakprotection.alert.cta1" = "Désactiver"; +"dashboard.vpn.leakprotection.alert.cta2" = "En savoir plus"; +"dashboard.vpn.leakprotection.alert.cta3" = "Ignorer"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "Pour éviter les fuites de données, appuyez sur « Changer » afin de passer au protocole VPN IKEv2 et de permettre la reconnexion automatique."; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "Changer"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "Nous espérons que notre produit VPN répond à vos attentes"; "rating.problems.question" = "Quel était le problème ?"; "rating.problems.subtitle" = "Vous voulez nous envoyer un commentaire ? Nous pouvons vous aider à améliorer votre expérience sur PIA"; -"rating.rate.question" = "Et un avis sur l'App Store ?"; +"rating.review.question" = "Et un avis sur l'App Store ?"; +"rating.rate.question" = "Et une note sur l’App Store ?"; "rating.rate.subtitle" = "Nous apprécions que vous partagiez votre expérience"; "rating.error.question" = "La connexion n'a pas pu être établie"; "rating.error.subtitle" = "Vous pouvez essayer de sélectionner une autre région ou de nous en informer en ouvrant un ticket de support."; "rating.error.button.send" = "Envoyer un commentaire"; +"rating.alert.button.notreally" = "Non merci"; +"rating.alert.button.nothanks" = "Non, merci."; +"rating.alert.button.oksure" = "Bien sûr !"; // CALLING CARDS "card.wireguard.title" = "Essayez WireGuard® aujourd'hui !"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "Votre adresse IP dédiée a été activée avec succès. Elle sera disponible dans votre liste de sélection de région."; "dedicated.ip.message.expired.token" = "Votre jeton est expiré. Veuillez en générer un nouveau à partir de la page de votre compte sur le site Web."; "dedicated.ip.message.error.token" = "Votre jeton est expiré. Veuillez en générer un nouveau à partir de la page de votre compte sur le site Web."; +"dedicated.ip.message.error.retryafter" = "Nombre trop élevé de demandes d’activation de jeton manquées. Veuillez réessayer dans %@ seconde(s)."; "dedicated.ip.message.token.willexpire" = "Votre adresse IP dédiée expirera bientôt. Obtenez-en une nouvelle"; "dedicated.ip.message.token.willexpire.link" = "Obtenez-en une nouvelle"; "dedicated.ip.message.ip.updated" = "Votre IP dédiée a été mise à jour"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "Afficher les messages de communication de service"; "inapp.messages.settings.updated" = "Les paramètres ont été mis à jour"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "Région"; +"widget.liveActivity.protocol.title" = "Protocole"; diff --git a/PIA VPN/it.lproj/Localizable.strings b/PIA VPN/it.lproj/Localizable.strings index f74c2389e..5fef616f0 100644 --- a/PIA VPN/it.lproj/Localizable.strings +++ b/PIA VPN/it.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "Rinnovo"; "expiration.message" = "Il tuo abbonamento scade presto. Rinnovalo per mantenere la protezione."; +"local_notification.non_compliant_wifi.title" = "Wi-Fi non protetto: %@"; +"local_notification.non_compliant_wifi.text" = "Tocca qui per proteggere il tuo dispositivo"; + // SHORTCUTS "shortcuts.connect" = "Connetti"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "Piano mensile"; "account.subscriptions.trial" = "Piano di prova"; "account.unauthorized" = "Qualcosa è andato storto. Prova ad accedere di nuovo"; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "Elimina account"; +"account.delete.alert.title" = "Continuare?"; +"account.delete.alert.message" = "L’eliminazione del tuo account PIA è un’operazione definitiva e irreversibile, al termine della quale non potrai più recuperare le tue credenziali PIA. Tieni presente che questa azione elimina solo il tuo account PIA dal nostro database, NON l’abbonamento. Per cancellare l’abbonamento a Private Internet Access, dovrai accedere al tuo account Apple e cancellarlo da lì. Altrimenti continuerai a pagarlo anche se il tuo account PIA non sarà più attivo."; +"account.delete.alert.failureMessage" = "Qualcosa non ha funzionato durante l’eliminazione dell’account. Riprova più tardi."; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "Tema attivo"; "settings.application_settings.kill_switch.title" = "Killswitch VPN"; "settings.application_settings.kill_switch.footer" = "Il killswitch VPN impedisce l'accesso a Internet quando la connessione VPN si sta riconnettendo. Questo esclude la disconnessione manuale."; +"settings.application_settings.leak_protection.title" = "Protezione perdita dati"; +"settings.application_settings.leak_protection.footer" = "iOS include funzioni per operare di default al di fuori della VPN, come AirDrop, CarPlay, AirPlay e hotspot personali. L’attivazione di una protezione personalizzata contro la perdita dei dati instrada questo traffico attraverso la VPN, ma può influire su queste funzioni. Ulteriori informazioni"; +"settings.application_settings.leak_protection.more_info" = "Ulteriori informazioni"; +"settings.application_settings.allow_local_network.title" = "Consenti l’accesso ai dispositivi sulla rete locale"; +"settings.application_settings.allow_local_network.footer" = "Rimani connesso ai dispositivi locali come stampanti o file server durante la connessione alla VPN. (Consenti solo se ti fidi delle persone e dei dispositivi sulla rete.)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™ blocca pubblicità, tracker e malware mentre sei connesso alla VPN."; +"settings.application_settings.leak_protection.alert.title" = "Le modifiche alle impostazioni della VPN avranno effetto alla prossima connessione"; "settings.content_blocker.title" = "Stato di blocco contenuti Safari"; "settings.content_blocker.state.title" = "Stato corrente"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "Pulsante di connessione VPN. VPN attualmente connesso"; "dashboard.accessibility.vpn.button.isOff" = "Pulsante di connessione VPN. VPN attualmente disconnesso"; +"dashboard.vpn.leakprotection.alert.title" = "Rilevato Wi-Fi non sicuro"; +"dashboard.vpn.leakprotection.alert.message" = "Per prevenire perdite di dati, tocca Disabilita ora per disattivare “Consenti l’accesso ai dispositivi sulla rete locale“ e riconnettersi automaticamente."; +"dashboard.vpn.leakprotection.alert.cta1" = "Disabilita ora"; +"dashboard.vpn.leakprotection.alert.cta2" = "Ulteriori informazioni"; +"dashboard.vpn.leakprotection.alert.cta3" = "Ignora"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "Per prevenire le perdite di dati, tocca Cambia ora per passare al protocollo VPN IKEv2 e riconnettersi automaticamente."; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "Cambia ora"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "Speriamo che il nostro prodotto VPN soddisfi le tue aspettative"; "rating.problems.question" = "Cosa non ha funzionato?"; "rating.problems.subtitle" = "Vuoi offrire il tuo feedback? Possiamo aiutarti a migliorare la tua esperienza d'uso di PIA"; -"rating.rate.question" = "Che ne pensi di condividere una recensione sull'AppStore?"; +"rating.review.question" = "Che ne pensi di condividere una recensione sull'AppStore?"; +"rating.rate.question" = "Che ne dici di una valutazione su App Store?"; "rating.rate.subtitle" = "Grazie per aver condiviso la tua esperienza"; "rating.error.question" = "Impossibile stabilire la connessione"; "rating.error.subtitle" = "Puoi provare a selezionare un altro paese o comunicarcelo aprendo un ticket di supporto."; "rating.error.button.send" = "Invia feedback"; +"rating.alert.button.notreally" = "No, grazie"; +"rating.alert.button.nothanks" = "No, grazie."; +"rating.alert.button.oksure" = "Certo!"; // CALLING CARDS "card.wireguard.title" = "Prova subito WireGuard®!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "Il tuo IP dedicato è stato attivato. Sarà disponibile nell'elenco di selezione del paese."; "dedicated.ip.message.expired.token" = "Token scaduto. Generane uno nuovo dalla pagina del tuo account sul sito web."; "dedicated.ip.message.error.token" = "Token scaduto. Generane uno nuovo dalla pagina del tuo account sul sito web."; +"dedicated.ip.message.error.retryafter" = "Troppe richieste di attivazione token non riuscite. Riprova tra %@ secondo/i."; "dedicated.ip.message.token.willexpire" = "Il tuo IP dedicato scade a breve. Ottieni uno nuovo"; "dedicated.ip.message.token.willexpire.link" = "Ottieni uno nuovo"; "dedicated.ip.message.ip.updated" = "Il tuo IP dedicato è aggiornato"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "Mostra i messaggi di comunicazione sul servizio"; "inapp.messages.settings.updated" = "Impostazioni aggiornate"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "Area"; +"widget.liveActivity.protocol.title" = "Protocollo"; diff --git a/PIA VPN/ja.lproj/Localizable.strings b/PIA VPN/ja.lproj/Localizable.strings index b328b549f..fea22e5db 100644 --- a/PIA VPN/ja.lproj/Localizable.strings +++ b/PIA VPN/ja.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "更新"; "expiration.message" = "ご利用のサブスクリプションがもうすぐ期限切れとなります。更新して保護された状態を保ちましょう。"; +"local_notification.non_compliant_wifi.title" = "保護されていないWiFi:%@"; +"local_notification.non_compliant_wifi.text" = "お使いのデバイスを保護するには、ここをタップしてください"; + // SHORTCUTS "shortcuts.connect" = "接続"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "月間プラン"; "account.subscriptions.trial" = "トライアルプラン"; "account.unauthorized" = "問題が発生しました。もう一度ログインしてみてください"; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "アカウントを削除"; +"account.delete.alert.title" = "本当によろしいですか?"; +"account.delete.alert.message" = "PIA アカウントの削除は永久的な操作であり、元に戻すことはできません。この操作を実行した後に、お持ちのPIA資格情報を取得することはできません。この操作ではお持ちのPIAアカウントが削除されるだけで、ご契約が削除されるわけではないことにご留意ください。お持ちのAppleアカウントにアクセスし、そこでPrivate Internet Access契約をキャンセルしない限り、お持ちのPIAアカウントが無効になった後も請求が行われます。"; +"account.delete.alert.failureMessage" = "お持ちのアカウントを削除中に問題が発生しました。後でもう一度試してください。"; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "アクティブなテーマ"; "settings.application_settings.kill_switch.title" = "VPNキルスイッチ"; "settings.application_settings.kill_switch.footer" = "VPNキルスイッチは、VPNの再接続時にインターネット接続を無効にします。これには手動での切断が含まれません。"; +"settings.application_settings.leak_protection.title" = "漏えい防止"; +"settings.application_settings.leak_protection.footer" = "iOSには、デフォルトでAirDrop、CarPlay、AirPlay、パーソナルホットスポットなど、VPNの外部で動作するように設計された機能が含まれています。カスタムリーク保護機能を有効にすると、このトラフィックはVPN経由でルーティングされますが、これらの機能の動作に影響する可能性があります。詳細"; +"settings.application_settings.leak_protection.more_info" = "詳細"; +"settings.application_settings.allow_local_network.title" = "ローカルネットワーク内のデバイスへのアクセスを許可"; +"settings.application_settings.allow_local_network.footer" = "VPNに接続している間、プリンタやファイルサーバーなどのローカルデバイスへの接続を維持できます(ネットワーク内のユーザーとデバイスを信頼できる場合にのみ許可してください。)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™はVPNに接続されている間、広告、閲覧行動の追跡、そしてマルウェアをブロックします。"; +"settings.application_settings.leak_protection.alert.title" = "VPN設定への変更は次回の接続時に反映されます"; "settings.content_blocker.title" = "Safariコンテンツブロッカーの状態"; "settings.content_blocker.state.title" = "現在の状況"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "VPN接続ボタン。VPNに現在接続されています"; "dashboard.accessibility.vpn.button.isOff" = "VPN接続ボタン。VPNは現在切断されています"; +"dashboard.vpn.leakprotection.alert.title" = "保護されていないWiFiが検出されました"; +"dashboard.vpn.leakprotection.alert.message" = "データ漏洩を防ぐには、[今すぐ無効にする]をタップして[ローカルネットワーク内のデバイスへのアクセスを許可]をオフにし、自動的に再接続してください。"; +"dashboard.vpn.leakprotection.alert.cta1" = "今すぐ無効にする"; +"dashboard.vpn.leakprotection.alert.cta2" = "詳細"; +"dashboard.vpn.leakprotection.alert.cta3" = "無視"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "データ漏洩を防ぐには、[今すぐ切り替える]をタップしてIKEv2 VPNプロトコルに変更し、自動的に再接続してください。"; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "今すぐ切り替える"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "VPN製品にご満足いただいていることを願っています"; "rating.problems.question" = "どのような問題があったのでしょうか?"; "rating.problems.subtitle" = "フィードバックを送信しますか?PIAご利用にあたり、お客様のエクスペリエンス改善のお手伝いをいたします。"; -"rating.rate.question" = "AppStoreでレビューしていただけますか?"; +"rating.review.question" = "AppStoreでレビューしていただけますか?"; +"rating.rate.question" = "AppStoreで評価していただけますか?"; "rating.rate.subtitle" = "お客様のご感想を共有していただければありがたいです"; "rating.error.question" = "接続を確立できませんでした"; "rating.error.subtitle" = "別の地域を選択するか、サポートチケットを開いてそれについてお知らせください。"; "rating.error.button.send" = "フィードバックを送信"; +"rating.alert.button.notreally" = "いいえ"; +"rating.alert.button.nothanks" = "いいえ、結構です"; +"rating.alert.button.oksure" = "はい、評価します"; // CALLING CARDS "card.wireguard.title" = "WireGuard®を今すぐお試しください!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "専用IPが正常にアクティベートされました。地域選択リストで利用できるようになります。"; "dedicated.ip.message.expired.token" = "トークンの有効期限が切れています。ウェブサイトのアカウントページから新しいトークンを生成してください。"; "dedicated.ip.message.error.token" = "トークンの有効期限が切れています。ウェブサイトのアカウントページから新しいトークンを生成してください。"; +"dedicated.ip.message.error.retryafter" = "失敗したトークン有効化リクエストの数が多すぎます。%@秒後にもう一度お試しください。"; "dedicated.ip.message.token.willexpire" = "あなたの専用IPは間もなく期限が切れます。新しい専用IPを入手してください"; "dedicated.ip.message.token.willexpire.link" = "新しい専用IPを入手してください"; "dedicated.ip.message.ip.updated" = "あなたの専用IPが更新されました"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "サービス通信メッセージを表示"; "inapp.messages.settings.updated" = "設定が更新されました"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "地域"; +"widget.liveActivity.protocol.title" = "プロトコル"; diff --git a/PIA VPN/ko.lproj/Localizable.strings b/PIA VPN/ko.lproj/Localizable.strings index 1aa9b6a92..029680fff 100644 --- a/PIA VPN/ko.lproj/Localizable.strings +++ b/PIA VPN/ko.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "갱신"; "expiration.message" = "구독이 곧 만료됩니다. 갱신하여 계속 보호를 받으세요."; +"local_notification.non_compliant_wifi.title" = "비보안 Wi-Fi: %@"; +"local_notification.non_compliant_wifi.text" = "장치를 보호하려면 여기를 누르세요."; + // SHORTCUTS "shortcuts.connect" = "연결"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "월간 플랜"; "account.subscriptions.trial" = "체험 플랜"; "account.unauthorized" = "문제가 발생했습니다. 다시 로그인해 보세요"; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "계정 삭제"; +"account.delete.alert.title" = "계속하시겠습니까?"; +"account.delete.alert.message" = "PIA 계정 삭제는 영구적이고 되돌릴 수 없습니다. 이 작업을 수행한 후에는 PIA 인증 정보를 복구할 수 없습니다. 이 작업은 본사 데이터베이스에서 사용자의 PIA 계정만 삭제합니다. 사용자의 구독은 삭제되지 않습니다. 따라서 자신의 Apple 계정으로 이동해서 Private Internet Access 구독을 취소해야 합니다. 그렇지 않으면 PIA를 더 이상 사용할 수 없더라도 요금이 부과됩니다."; +"account.delete.alert.failureMessage" = "계정을 삭제하는 중 문제가 발생했습니다. 나중에 다시 시도하십시오."; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "활성화된 테마"; "settings.application_settings.kill_switch.title" = "VPN 킬 스위치"; "settings.application_settings.kill_switch.footer" = "VPN 킬 스위치는 VPN 연결이 다시 연결 중이면 인터넷에 대한 액세스를 방지합니다. 수동으로 연결을 해제하는 경우는 제외입니다."; +"settings.application_settings.leak_protection.title" = "보호 누출"; +"settings.application_settings.leak_protection.footer" = "iOS에는 기본적으로 AirDrop, CarPlay, AirPlay, 개인 핫스팟과 같이 VPN 외부에서 작동하도록 설계된 기능이 포함됩니다. 사용자 지정 누출 보호를 활성화하면 이 트래픽이 VPN을 통해 라우팅되지만 이러한 기능의 작동 방식에 영향을 줄 수 있습니다. 자세히 알아보기"; +"settings.application_settings.leak_protection.more_info" = "자세히 알아보기"; +"settings.application_settings.allow_local_network.title" = "로컬 네트워크의 장치 액세스 허용"; +"settings.application_settings.allow_local_network.footer" = "VPN에 연결된 상태에서 프린터 또는 파일 서버와 같은 로컬 장치 연결을 유지하세요. (네트워크의 사용자 및 장치를 신뢰하는 경우에만 이 옵션 허용)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™는 VPN에 연결되어 있을 때 광고, 트래커 및 악성코드를 차단합니다."; +"settings.application_settings.leak_protection.alert.title" = "VPN 설정을 변경하면 다음에 연결할 때 적용됩니다."; "settings.content_blocker.title" = "Safari 콘텐츠 차단기 상태"; "settings.content_blocker.state.title" = "현재 상태"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "VPN 연결 버튼. VPN이 현재 연결되었습니다"; "dashboard.accessibility.vpn.button.isOff" = "VPN 연결 버튼. VPN이 현재 연결 해제되었습니다"; +"dashboard.vpn.leakprotection.alert.title" = "안전하지 않은 Wi-Fi 감지됨"; +"dashboard.vpn.leakprotection.alert.message" = "데이터 누출을 방지하려면 지금 비활성화를 눌러서 \"로컬 네트워크의 장치 액세스 허용\"을 해제하고 자동으로 다시 연결하세요."; +"dashboard.vpn.leakprotection.alert.cta1" = "지금 비활성화"; +"dashboard.vpn.leakprotection.alert.cta2" = "자세히 알아보기"; +"dashboard.vpn.leakprotection.alert.cta3" = "무시"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "데이터 누출을 방지하려면 지금 전환을 눌러서 IKEv2 VPN 프로토콜로 변경하고 자동으로 다시 연결하세요."; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "지금 전환"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "저희 VPN 제품이 고객님의 기대에 부응하기를 바랍니다"; "rating.problems.question" = "어떤 문제가 있었습니까?"; "rating.problems.subtitle" = "피드백을 보내 주시겠습니까? 더 나은 PIA를 경험하실 수 있도록 도와 드리겠습니다"; -"rating.rate.question" = "App Store에 리뷰를 남겨 주시겠습니까?"; +"rating.review.question" = "App Store에 리뷰를 남겨 주시겠습니까?"; +"rating.rate.question" = "App Store에서 점수를 매겨주시겠어요?"; "rating.rate.subtitle" = "고객님의 경험을 공유해 주시면 감사하겠습니다"; "rating.error.question" = "연결을 수립할 수 없습니다"; "rating.error.subtitle" = "다른 지역을 선택해 보시거나 지원 티켓을 열어서 저희에게 알려 주세요."; "rating.error.button.send" = "피드백 보내기"; +"rating.alert.button.notreally" = "아니요"; +"rating.alert.button.nothanks" = "아니요."; +"rating.alert.button.oksure" = "네, 좋아요!"; // CALLING CARDS "card.wireguard.title" = "지금 WireGuard®를 사용해 보세요!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "회원님의 전용 IP가 성공적으로 활성화되었습니다. 지역 선택 목록에서 사용하실 수 있습니다."; "dedicated.ip.message.expired.token" = "회원님의 토큰은 만료되었습니다. 웹사이트의 계정 페이지에서 새로운 토큰을 생성하세요."; "dedicated.ip.message.error.token" = "회원님의 토큰은 만료되었습니다. 웹사이트의 계정 페이지에서 새로운 토큰을 생성하세요."; +"dedicated.ip.message.error.retryafter" = "토큰 활성화 요청이 너무 많이 실패했습니다. %@초 후 다시 시도하십시오."; "dedicated.ip.message.token.willexpire" = "회원님의 전용 IP가 곧 만료됩니다. 새로 획득하세요"; "dedicated.ip.message.token.willexpire.link" = "새로 획득하세요"; "dedicated.ip.message.ip.updated" = "회원님의 전용 IP가 업데이트되었습니다"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "서비스 통신 메시지 표시"; "inapp.messages.settings.updated" = "설정이 업데이트되었습니다"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "지역"; +"widget.liveActivity.protocol.title" = "프로토콜"; diff --git a/PIA VPN/nb.lproj/Localizable.strings b/PIA VPN/nb.lproj/Localizable.strings index ed4416b06..bed2092a0 100644 --- a/PIA VPN/nb.lproj/Localizable.strings +++ b/PIA VPN/nb.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "Forny"; "expiration.message" = "Abonnementet ditt utløper snart. Forny det for å forbli beskyttet."; +"local_notification.non_compliant_wifi.title" = "Usikret WiFi:%@"; +"local_notification.non_compliant_wifi.text" = "Trykk her for å sikre enheten din"; + // SHORTCUTS "shortcuts.connect" = "Koble til"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "Månedsplan"; "account.subscriptions.trial" = "Prøveplan"; "account.unauthorized" = "Noe gikk galt. Prøv å logge inn igjen."; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "Slett konto"; +"account.delete.alert.title" = "Er du sikker?"; +"account.delete.alert.message" = "Sletting av PIA-kontoen er permanent og kan ikke reverseres. Du vil ikke kunne hente PIA-legitimasjonen etter at denne handlingen er utført. Vær oppmerksom på at denne handlingen bare sletter PIA-kontoen fra databasen, og sletter IKKE abonnementet. Du må gå til Apple-kontoen og kansellere abonnementet på Private Internet Access derfra. Ellers blir du fortsatt belastet, selv om PIA-kontoen ikke lenger er aktiv."; +"account.delete.alert.failureMessage" = "Noe gikk galt ved sletting av kontoen. Prøv på nytt senere."; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "Aktivt tema"; "settings.application_settings.kill_switch.title" = "Kill switch for VPN"; "settings.application_settings.kill_switch.footer" = "Kill switch for VPN hindrer tilgang til Internett hvis VPN-tilkoblingen mister forbindelsen og prøver å koble til igjen. Dette ekskluderer manuell frakobling."; +"settings.application_settings.leak_protection.title" = "Lekkasjebeskyttelse"; +"settings.application_settings.leak_protection.footer" = "iOS har funksjoner som er utviklet for å fungere utenfor VPN-et, for eksempel AirDrop, CarPlay, AirPlay og delt Internett. Ved å aktivere tilpasset lekkasjebeskyttelse kan du rute denne trafikken gjennom VPN-et, men det kan påvirke hvordan disse funksjonene fungerer. Mer informasjon"; +"settings.application_settings.leak_protection.more_info" = "Mer informasjon"; +"settings.application_settings.allow_local_network.title" = "Tillat tilgang til enheter på lokalnettverk"; +"settings.application_settings.allow_local_network.footer" = "Behold tilgang til lokale enheter som skrivere eller filservere mens du er koblet til VPN-et. (Tillat dette bare hvis du stoler på personene og enhetene på nettverket ditt.)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™ blokkerer reklamer, sporere og skadelig programvare når du er koblet til VPN-en."; +"settings.application_settings.leak_protection.alert.title" = "Endringer i VPN-innstillingene vil tre i kraft ved neste tilkobling"; "settings.content_blocker.title" = "Safari Innholdsblokkerer – status"; "settings.content_blocker.state.title" = "Gjeldene status"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "VPN-tilkoblingsknapp. VPN-klienten er for øyeblikket tilkoblet"; "dashboard.accessibility.vpn.button.isOff" = "VPN-tilkoblingsknapp. VPN-klienten er for øyeblikket frakoblet"; +"dashboard.vpn.leakprotection.alert.title" = "Usikret WiFi oppdaget"; +"dashboard.vpn.leakprotection.alert.message" = "For å hindre datalekkasjer trykker du på Deaktiver nå for å slå av \"Tillat tillat tilgang til enheter på lokalnettverk\" og automatisk koble til på nytt."; +"dashboard.vpn.leakprotection.alert.cta1" = "Deaktiver nå"; +"dashboard.vpn.leakprotection.alert.cta2" = "Les mer"; +"dashboard.vpn.leakprotection.alert.cta3" = "Ignorer"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "For å hindre datalekkasjer trykker du på Bytt nå for å bytte til VPN-protokollen IKEv2 og automatisk koble til på nytt."; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "Bytt nå"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "Vi håper VPN-produktet svarer til forventningene dine"; "rating.problems.question" = "Hva gikk galt?"; "rating.problems.subtitle" = "Ønsker du å sende en tilbakemelding? Vi kan bidra til å forbedre opplevelsen din med PIA"; -"rating.rate.question" = "Hva med en anmeldelse på AppStore?"; +"rating.review.question" = "Hva med en anmeldelse på AppStore?"; +"rating.rate.question" = "Hva med en vurdering i AppStore?"; "rating.rate.subtitle" = "Vi setter pris på at du deler opplevelsen din"; "rating.error.question" = "Tilkoblingen kunne ikke opprettes"; "rating.error.subtitle" = "Du kan velge en annen region eller fortelle oss om det ved å åpne en støttesak."; "rating.error.button.send" = "Send tilbakemelding"; +"rating.alert.button.notreally" = "Ikke egentlig"; +"rating.alert.button.nothanks" = "Nei takk."; +"rating.alert.button.oksure" = "Klart det!"; // CALLING CARDS "card.wireguard.title" = "Prøv WireGuard® i dag!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "Den dedikerte IP-en din ble aktivert. Den blir tilgjengelig i regionvalg-listen."; "dedicated.ip.message.expired.token" = "Tokenet er utløpt. Generer et nytt et fra kontosiden din på nettstedet."; "dedicated.ip.message.error.token" = "Tokenet er utløpt. Generer et nytt et fra kontosiden din på nettstedet."; +"dedicated.ip.message.error.retryafter" = "For mange mislykkede forespørsler om aktivering av token. Prøv på nytt etter %@ sekund(er)."; "dedicated.ip.message.token.willexpire" = "Den dedikerte IP-en din utløper snart. Skaff deg en ny en"; "dedicated.ip.message.token.willexpire.link" = "Skaff deg en ny en"; "dedicated.ip.message.ip.updated" = "Den dedikerte IP-en din ble oppdatert"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "Vis tjenestekommunikasjonsmeldinger"; "inapp.messages.settings.updated" = "Innstillingene ble oppdatert"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "Region"; +"widget.liveActivity.protocol.title" = "Protokoll"; diff --git a/PIA VPN/nl.lproj/Localizable.strings b/PIA VPN/nl.lproj/Localizable.strings index 20d904003..c6153cfd9 100644 --- a/PIA VPN/nl.lproj/Localizable.strings +++ b/PIA VPN/nl.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "Vernieuwing"; "expiration.message" = "Uw abonnement verloopt binnenkort. Vernieuw uw abonnement om beschermd te blijven."; +"local_notification.non_compliant_wifi.title" = "Onbeveiligde wifi: %@"; +"local_notification.non_compliant_wifi.text" = "Tik hier om je apparaat te beschermen"; + // SHORTCUTS "shortcuts.connect" = "Verbinden"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "Maandelijks abonnement"; "account.subscriptions.trial" = "Proefabonnement"; "account.unauthorized" = "Er is iets fout gegaan. Probeer opnieuw in te loggen."; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "Verwijder account"; +"account.delete.alert.title" = "Weet u het zeker?"; +"account.delete.alert.message" = "Het verwijderen van uw PIA-account is definitief en onomkeerbaar. U zult uw PIA-inloggegevens niet kunnen ophalen na het uitvoeren van deze actie. Houd ermee rekening dat deze actie alleen uw PIA-account verwijdert uit onze database, maar NIET uw abonnement. Hiervoor moet u naar uw Apple-account gaan en daar het Private Internet Access-abonnement annuleren. Anders worden u nog steeds kosten aangerekend, hoewel uw PIA-account niet langer actief is."; +"account.delete.alert.failureMessage" = "Er ging iets fout bij het verwijderen van uw account. Probeer het later nog een keer."; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "Actief thema"; "settings.application_settings.kill_switch.title" = "VPN-killswitch"; "settings.application_settings.kill_switch.footer" = "De VPN kill switch voorkomt toegang tot internet als de VPN-verbinding opnieuw tot stand wordt gebracht. Dit geldt niet wanneer de verbinding handmatig wordt verbroken."; +"settings.application_settings.leak_protection.title" = "Lekbescherming"; +"settings.application_settings.leak_protection.footer" = "iOS bevat functies die ontworpen zijn om standaard te werken buiten het VPN, zoals AirDrop, CarPlay, AirPlay en persoonlijke hotspots. Het inschakelen van aangepaste lekbescherming leidt dit verkeer om via het VPN, maar kan de werking van deze functies beïnvloeden. Meer info"; +"settings.application_settings.leak_protection.more_info" = "Meer info"; +"settings.application_settings.allow_local_network.title" = "Sta toegang toe tot apparaten op een lokaal netwerk"; +"settings.application_settings.allow_local_network.footer" = "Blijf verbonden met lokale apparaten, zoals printers of bestandsservers die verbonden zijn met het VPN. (Sta dit alleen toe als je de personen en apparaten op je netwerk vertrouwt.)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™ blokkeert advertenties, trackers en malware als u met de VPN bent verbonden."; +"settings.application_settings.leak_protection.alert.title" = "Wijzigingen aan de VPN-instellingen worden van kracht bij de volgende verbinding"; "settings.content_blocker.title" = "Status Safari Content Blocker"; "settings.content_blocker.state.title" = "Huidige status"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "VPN-verbindingsknop. De VPN is verbonden"; "dashboard.accessibility.vpn.button.isOff" = "VPN-verbindingsknop. De VPN is niet verbonden"; +"dashboard.vpn.leakprotection.alert.title" = "Onbeveiligde wifi gedetecteerd"; +"dashboard.vpn.leakprotection.alert.message" = "Om gegevenslekken te voorkomen, tik je op \"Schakel nu uit\" om \"Sta toegang toe tot apparaten op een lokaal netwerk\" uit te schakelen en automatisch opnieuw verbinding te maken."; +"dashboard.vpn.leakprotection.alert.cta1" = "Schakel nu uit"; +"dashboard.vpn.leakprotection.alert.cta2" = "Meer informatie"; +"dashboard.vpn.leakprotection.alert.cta3" = "Negeer"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "Om gegevenslekken te voorkomen, tik je op \"Schakel nu\" om te wijzigen naar het IKEv2 VPN-protocol en automatisch opnieuw verbinding te maken."; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "Schakel nu"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "We hopen dat ons VPN-product aan uw verwachtingen voldoet"; "rating.problems.question" = "Wat is er fout gegaan?"; "rating.problems.subtitle" = "Wilt u feedback geven? We kunnen u helpen met het verbeteren van uw ervaring met PIA."; -"rating.rate.question" = "Waarom laat u geen beoordeling achter in de AppStore?"; +"rating.review.question" = "Waarom laat u geen beoordeling achter in de AppStore?"; +"rating.rate.question" = "Wilt u een waardering geven in de App Store?"; "rating.rate.subtitle" = "We stellen het op prijs dat u uw ervaring deelt"; "rating.error.question" = "De verbinding kan niet tot stand worden gebracht"; "rating.error.subtitle" = "U kunt een andere regio selecteren of ons hiervan op de hoogte stellen door een supportticket te openen."; "rating.error.button.send" = "Feedback sturen"; +"rating.alert.button.notreally" = "Niet echt"; +"rating.alert.button.nothanks" = "Nee, bedankt."; +"rating.alert.button.oksure" = "Graag!"; // CALLING CARDS "card.wireguard.title" = "Probeer WireGuard® vandaag nog!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "Uw dedicated IP is geactiveerd. Het is beschikbaar in uw regioselectielijst."; "dedicated.ip.message.expired.token" = "Uw code is verlopen. Genereer een nieuwe via uw accountpagina op de website."; "dedicated.ip.message.error.token" = "Uw code is verlopen. Genereer een nieuwe via uw accountpagina op de website."; +"dedicated.ip.message.error.retryafter" = "Teveel mislukte aanvragen voor het activeren van tokens. Probeer het opnieuw na %@ seconde(n)."; "dedicated.ip.message.token.willexpire" = "Uw dedicated IP verloopt binnenkort. Haal een nieuwe"; "dedicated.ip.message.token.willexpire.link" = "Haal een nieuwe"; "dedicated.ip.message.ip.updated" = "Uw dedicated IP is bijgewerkt"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "Service-communicatieberichten weergeven"; "inapp.messages.settings.updated" = "De instellingen zijn bijgewerkt"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "Regio"; +"widget.liveActivity.protocol.title" = "Protocol"; diff --git a/PIA VPN/pl.lproj/Localizable.strings b/PIA VPN/pl.lproj/Localizable.strings index 0866f2e5a..2e2f5fd85 100644 --- a/PIA VPN/pl.lproj/Localizable.strings +++ b/PIA VPN/pl.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "Odnowienie"; "expiration.message" = "Twoja subskrypcja wkrótce wygasa. Odnów ją, aby utrzymać ochronę."; +"local_notification.non_compliant_wifi.title" = "Niezabezpieczona sieć Wi-Fi: %@"; +"local_notification.non_compliant_wifi.text" = "Dotknij tutaj, aby zabezpieczyć urządzenie"; + // SHORTCUTS "shortcuts.connect" = "Połącz"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "Plan miesięczny"; "account.subscriptions.trial" = "Plan próbny"; "account.unauthorized" = "Coś poszło nie tak. zalogować się ponownie."; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "Usuń konto"; +"account.delete.alert.title" = "Czy na pewno?"; +"account.delete.alert.message" = "Usunięcie Twojego konta PIA będzie trwałe i nieodwracalne. Po tej akcji nie będziesz mógł pobrać swoich danych logowania PIA. Ta akcja powoduje tylko usunięcie konta PIA z naszej bazy danych, ale NIE powoduje usunięcia subskrypcji. W tym celu należy przejść do swojego konta Apple i anulować tam subskrypcję Private Internet Access. W przeciwnym razie nadal będą pobierane opłaty, mimo że konto PIA nie będzie już aktywne."; +"account.delete.alert.failureMessage" = "Coś poszło nie tak podczas usuwania konta, spróbuj jeszcze raz później."; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "Aktywny motyw"; "settings.application_settings.kill_switch.title" = "Wyłącznik awaryjny VPN"; "settings.application_settings.kill_switch.footer" = "Wyłącznik awaryjny VPN zapobiega dostępowi do internetu, jeśli połączenie VPN jest nawiązywane ponownie. Nie obejmuje to ręcznego rozłączenia."; +"settings.application_settings.leak_protection.title" = "Ochrona przed wyciekami"; +"settings.application_settings.leak_protection.footer" = "iOS zawiera funkcje zaprojektowane domyślnie do działania poza VPN, takie jak AirDrop, CarPlay, AirPlay i osobiste hotspoty. Włączenie niestandardowej ochrony przed wyciekiem kieruje ten ruch przez VPN, ale może wpłynąć na działanie tych funkcji. Więcej informacji"; +"settings.application_settings.leak_protection.more_info" = "Więcej informacji"; +"settings.application_settings.allow_local_network.title" = "Zezwól na dostęp do urządzeń w sieci lokalnej"; +"settings.application_settings.allow_local_network.footer" = "Pozostań w kontakcie z lokalnymi urządzeniami, takimi jak drukarki lub serwery plików, podczas połączenia z VPN. (Zezwalaj na to tylko wtedy, gdy ufasz osobom i urządzeniom w Twojej sieci)."; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™ blokuje reklamy, programy śledzące i złośliwe oprogramowanie w czasie połączenia przez VPN."; +"settings.application_settings.leak_protection.alert.title" = "Zmiany w Ustawieniach VPN zostaną zastosowane przy kolejnym nawiązaniu połączenia"; "settings.content_blocker.title" = "Stan blokady zawartości Safari"; "settings.content_blocker.state.title" = "Bieżący stan"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "Przycisk połączenia z VPN. VPN jest teraz podłączona."; "dashboard.accessibility.vpn.button.isOff" = "Przycisk połączenia z VPN. VPN jest teraz odłączona."; +"dashboard.vpn.leakprotection.alert.title" = "Wykryto niezabezpieczoną sieć Wi-Fi"; +"dashboard.vpn.leakprotection.alert.message" = "Aby zapobiec wyciekom danych, dotknij Wyłącz teraz, aby wyłączyć opcję „Zezwól na dostęp do urządzeń w sieci lokalnej” i automatycznie połączyć się ponownie."; +"dashboard.vpn.leakprotection.alert.cta1" = "Wyłącz teraz"; +"dashboard.vpn.leakprotection.alert.cta2" = "Dowiedz się więcej"; +"dashboard.vpn.leakprotection.alert.cta3" = "Ignoruj"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "Aby zapobiec wyciekom danych, dotknij opcji Przełącz teraz, aby zmienić protokół na IKEv2 VPN i automatycznie połączyć się ponownie."; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "Przełącz teraz"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "Mamy nadzieję, że nasz produkt VPN spełnia Twoje oczekiwania"; "rating.problems.question" = "Co poszło źle?"; "rating.problems.subtitle" = "Czy zechcesz podzielić się z nami swoją opinią? Może pomóc i sprawić, ze będzie Ci się lepiej korzystało z PIA"; -"rating.rate.question" = "A może napiszesz recenzję w App Store?"; +"rating.review.question" = "A może napiszesz recenzję w App Store?"; +"rating.rate.question" = "A może ocenisz nas w sklepie App Store?"; "rating.rate.subtitle" = "Będziemy wdzięczni za opowiedzenie o swoich doświadczeniach"; "rating.error.question" = "Nie udało się nawiązać połączenia"; "rating.error.subtitle" = "Możesz spróbować wybrać inny region lub powiadomić nas o tym, wypełniając zgłoszenie do pomocy technicznej."; "rating.error.button.send" = "Wyślij opinię"; +"rating.alert.button.notreally" = "Nie za bardzo"; +"rating.alert.button.nothanks" = "Nie, dziękuję."; +"rating.alert.button.oksure" = "OK, jasne!"; // CALLING CARDS "card.wireguard.title" = "Wypróbuj WireGuard® dzisiaj!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "Twój dedykowany adres IP został aktywowany. Będzie dostępny na liście wyboru regionu."; "dedicated.ip.message.expired.token" = "Twój token stracił ważność. Wygeneruj nowy na stronie swojego konta w serwisie."; "dedicated.ip.message.error.token" = "Twój token stracił ważność. Wygeneruj nowy na stronie swojego konta w serwisie."; +"dedicated.ip.message.error.retryafter" = "Za dużo nieprawidłowych żądań aktywacji tokena. Spróbuj ponownie za %@ s."; "dedicated.ip.message.token.willexpire" = "Twój dedykowany adres IP wkrótce wygasa. Kup nowy adres."; "dedicated.ip.message.token.willexpire.link" = "Kup nowy adres."; "dedicated.ip.message.ip.updated" = "Zaktualizowano Twój dedykowany adres IP"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "Pokaż komunikaty dotyczące komunikacji usługi"; "inapp.messages.settings.updated" = "Zaktualizowano ustawienia"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "Region"; +"widget.liveActivity.protocol.title" = "Protokół"; diff --git a/PIA VPN/pt-BR.lproj/Localizable.strings b/PIA VPN/pt-BR.lproj/Localizable.strings index fc79a486e..c4fa37acd 100644 --- a/PIA VPN/pt-BR.lproj/Localizable.strings +++ b/PIA VPN/pt-BR.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "Renovação"; "expiration.message" = "Sua assinatura expirará em breve. Renove para continuar protegido."; +"local_notification.non_compliant_wifi.title" = "Wi-Fi não seguro: %@"; +"local_notification.non_compliant_wifi.text" = "Toque aqui para proteger seu dispositivo"; + // SHORTCUTS "shortcuts.connect" = "Conectar"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "Plano mensal"; "account.subscriptions.trial" = "Plano de avaliação"; "account.unauthorized" = "Ocorreu um erro. Tente fazer login novamente."; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "Excluir conta"; +"account.delete.alert.title" = "Tem certeza?"; +"account.delete.alert.message" = "A exclusão da sua conta da PIA é permanente e irreversível. Você não poderá recuperar suas credenciais da PIA após executar essa ação. Observe que essa ação exclui apenas sua conta da PIA do nosso banco de dados, mas NÃO exclui sua assinatura. Você precisará ir até sua conta da Apple e cancelar a assinatura da Private Internet Access de lá. Caso contrário, você ainda será cobrado, mesmo que sua conta da PIA não esteja mais ativa."; +"account.delete.alert.failureMessage" = "Algo deu errado ao excluir sua conta. Tente de novo mais tarde."; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "Tema ativo"; "settings.application_settings.kill_switch.title" = "Kill switch de VPN"; "settings.application_settings.kill_switch.footer" = "O kill switch do VPN impede o acesso à internet se a conexão de VPN estiver se reconectando. Isto exclui a desconexão manual."; +"settings.application_settings.leak_protection.title" = "Proteção contra vazamentos"; +"settings.application_settings.leak_protection.footer" = "O iOS inclui recursos projetados para operar fora da VPN por padrão, como AirDrop, CarPlay, AirPlay e Acesso Pessoal. A ativação da proteção personalizada contra vazamentos roteia esse tráfego por meio da VPN, mas pode afetar o funcionamento desses recursos. Mais informações"; +"settings.application_settings.leak_protection.more_info" = "Mais informações"; +"settings.application_settings.allow_local_network.title" = "Permitir acesso a dispositivos na rede local"; +"settings.application_settings.allow_local_network.footer" = "Permaneça conectado a dispositivos locais, como impressoras ou servidores de arquivos, enquanto estiver conectado à VPN. (Permita essa opção apenas se você confiar nas pessoas e nos dispositivos da sua rede.)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "O PIA MACE™ bloqueia anúncios, rastreadores e malware enquanto você está conectado à VPN."; +"settings.application_settings.leak_protection.alert.title" = "As alterações nas configurações da VPN entrarão em vigor na próxima conexão"; "settings.content_blocker.title" = "Status do bloqueador de conteúdo do Safari"; "settings.content_blocker.state.title" = "Situação atual"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "Botão de conexão da VPN. A VPN está conectada no momento."; "dashboard.accessibility.vpn.button.isOff" = "Botão de conexão da VPN. A VPN está desconectada no momento."; +"dashboard.vpn.leakprotection.alert.title" = "Wi-Fi não seguro detectado"; +"dashboard.vpn.leakprotection.alert.message" = "Para evitar vazamentos de dados, toque em “Desabilitar agora” para desativar a opção “Permitir acesso a dispositivos na rede local” e reconectar automaticamente."; +"dashboard.vpn.leakprotection.alert.cta1" = "Desabilitar agora"; +"dashboard.vpn.leakprotection.alert.cta2" = "Saiba mais"; +"dashboard.vpn.leakprotection.alert.cta3" = "Ignorar"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "Para evitar vazamentos de dados, toque em “Alternar agora” para mudar para o protocolo VPN IKEv2 e reconectar automaticamente."; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "Alternar agora"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "Esperamos que nosso produto de VPN atenda às suas expectativas"; "rating.problems.question" = "O que aconteceu de errado?"; "rating.problems.subtitle" = "Deseja dar seu feedback? Podemos ajudá-lo a melhorar sua experiência com o uso da PIA"; -"rating.rate.question" = "Que tal uma avaliação na App Store?"; +"rating.review.question" = "Que tal uma avaliação na App Store?"; +"rating.rate.question" = "Que tal uma classificação na App Store?"; "rating.rate.subtitle" = "Agradecemos o compartilhamento da sua experiência"; "rating.error.question" = "Não foi possível estabelecer a conexão"; "rating.error.subtitle" = "Você pode tentar selecionar uma região diferente ou nos contar o que aconteceu abrindo um tíquete de suporte."; "rating.error.button.send" = "Enviar feedback"; +"rating.alert.button.notreally" = "Não, obrigado"; +"rating.alert.button.nothanks" = "Não, obrigado."; +"rating.alert.button.oksure" = "Sim, claro!"; // CALLING CARDS "card.wireguard.title" = "Experimente o WireGuard® hoje mesmo!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "O seu IP dedicado foi ativado com sucesso. Ele estará disponível em sua lista de seleção de regiões."; "dedicated.ip.message.expired.token" = "Seu token expirou. Gere um novo na página da sua conta no site."; "dedicated.ip.message.error.token" = "Seu token expirou. Gere um novo na página da sua conta no site."; +"dedicated.ip.message.error.retryafter" = "Muitas solicitações de ativação de token malsucedidas. Tente novamente após %@ segundo(s)."; "dedicated.ip.message.token.willexpire" = "O seu IP dedicado irá expirar em breve. Obtenha um novo"; "dedicated.ip.message.token.willexpire.link" = "Obtenha um novo"; "dedicated.ip.message.ip.updated" = "O seu IP dedicado foi atualizado"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "Mostrar mensagens de comunicação de serviço"; "inapp.messages.settings.updated" = "As configurações foram atualizadas"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "Região"; +"widget.liveActivity.protocol.title" = "Protocolo"; diff --git a/PIA VPN/ru.lproj/Localizable.strings b/PIA VPN/ru.lproj/Localizable.strings index 0a0df92ab..b5e47cc79 100644 --- a/PIA VPN/ru.lproj/Localizable.strings +++ b/PIA VPN/ru.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "Продление"; "expiration.message" = "Срок действия подписки истекает в ближайшее время. Продлите подписку, чтобы не потерять защиту."; +"local_notification.non_compliant_wifi.title" = "Незащищенная сеть Wi-Fi: %@"; +"local_notification.non_compliant_wifi.text" = "Нажмите здесь, чтобы защитить ваше устройство"; + // SHORTCUTS "shortcuts.connect" = "Подключиться"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "Месячный план"; "account.subscriptions.trial" = "Пробный план"; "account.unauthorized" = "Что-то пошло не так. Попробуйте выполнить вход еще раз"; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "Удалить аккаунт"; +"account.delete.alert.title" = "Вы уверены?"; +"account.delete.alert.message" = "Удаление аккаунта PIA окончательно и необратимо. Выполнив это действие, вы не сможете восстановить свои учетные данные PIA. Обратите внимание, что это действие приведет только к удалению аккаунта из нашей базы данных, Но НЕ к удалению подписки. Вам потребуется перейти в аккаунт Apple и отменить подписку на Private Internet Access. В противном случае плата будет начисляться даже в отсутствие активного аккаунта PIA."; +"account.delete.alert.failureMessage" = "При удалении аккаунта что-то пошло не так. Повторите попытку позже."; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "Активная тема"; "settings.application_settings.kill_switch.title" = "Авторазрыв соединения"; "settings.application_settings.kill_switch.footer" = "Функция авторазрыва соединения рвет Интернет-соединение при отключении VPN. Она не срабатывает при ручном отключении VPN."; +"settings.application_settings.leak_protection.title" = "Защита от утечек"; +"settings.application_settings.leak_protection.footer" = "iOS включает функции, по умолчанию предназначенные для работы вне VPN, такие как AirDrop, CarPlay, AirPlay и Персональная точка доступа. Включение защиты от утечек перенаправляет этот трафик через VPN, но может отразиться на работе этих функций. Подробнее"; +"settings.application_settings.leak_protection.more_info" = "Подробнее"; +"settings.application_settings.allow_local_network.title" = "Разрешить доступ к устройствам в локальной сети"; +"settings.application_settings.allow_local_network.footer" = "Оставайтесь подключенными к устройствам в локальной сети, таким как принтеры или файловые серверы, пользуясь при этом VPN-подключением (включайте эту опцию только если доверяете людям и устройствам в вашей сети.)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™ блокирует рекламу, следящие программы и вредоносное ПО, когда вы подключены к VPN."; +"settings.application_settings.leak_protection.alert.title" = "Изменения в настройках VPN будут применены при следующем подключении"; "settings.content_blocker.title" = "Состояние блокировщика контента для Safari"; "settings.content_blocker.state.title" = "Текущее состояние"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "Кнопка VPN-подключения. VPN сейчас подключен"; "dashboard.accessibility.vpn.button.isOff" = "Кнопка VPN-подключения. VPN сейчас отключен"; +"dashboard.vpn.leakprotection.alert.title" = "Обнаружена незащищенная сеть Wi-Fi"; +"dashboard.vpn.leakprotection.alert.message" = "Во избежание утечек данных, нажмите «Отключить сейчас», чтобы выключить опцию «Разрешить доступ к устройствам в локальной сети» и автоматически переподключиться."; +"dashboard.vpn.leakprotection.alert.cta1" = "Отключить сейчас"; +"dashboard.vpn.leakprotection.alert.cta2" = "Узнать больше"; +"dashboard.vpn.leakprotection.alert.cta3" = "Игнорировать"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "Для предотвращения утечек данных, нажмите «Переключить сейчас», чтобы перейти на протокол IKEv2 VPN и автоматически переподключиться."; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "Переключить сейчас"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "Надеемся, что наш продукт VPN соответствует вашим ожиданиям"; "rating.problems.question" = "Что пошло не так?"; "rating.problems.subtitle" = "Хотите дать отзыв? Мы сделаем все возможное, чтобы ваши впечатления от PIA стали лучше"; -"rating.rate.question" = "Как насчет отзыва в AppStore?"; +"rating.review.question" = "Как насчет отзыва в App Store?"; +"rating.rate.question" = "Как насчет оценки в App Store?"; "rating.rate.subtitle" = "Благодарим за согласие поделиться своим опытом"; "rating.error.question" = "Не удалось установить соединение"; "rating.error.subtitle" = "Попробуйте выбрать другой регион или расскажите нам, что произошло, открыв заявку в службу поддержки."; "rating.error.button.send" = "Отправить отзыв"; +"rating.alert.button.notreally" = "Не особо"; +"rating.alert.button.nothanks" = "Спасибо, не надо."; +"rating.alert.button.oksure" = "С удовольствием!"; // CALLING CARDS "card.wireguard.title" = "Опробуйте WireGuard® сегодня!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "Ваш выделенный IP-адрес успешно активирован. Теперь он будет доступен в списке выбора региона."; "dedicated.ip.message.expired.token" = "Срок действия вашего токена истек. Сгенерируйте новый на странице своей учетной записи на нашем веб-сайте."; "dedicated.ip.message.error.token" = "Срок действия вашего токена истек. Сгенерируйте новый на странице своей учетной записи на нашем веб-сайте."; +"dedicated.ip.message.error.retryafter" = "Слишком много неудачных запросов активации токена. Повторите попытку через %@ сек."; "dedicated.ip.message.token.willexpire" = "Действие вашего выделенного IP-адреса скоро заканчивается. Получите новый адрес"; "dedicated.ip.message.token.willexpire.link" = "Получите новый адрес"; "dedicated.ip.message.ip.updated" = "Ваш выделенный IP-адрес обновлен"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "Показать служебные сообщения обмена данными"; "inapp.messages.settings.updated" = "Настройки обновлены"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "Регион"; +"widget.liveActivity.protocol.title" = "Протокол"; diff --git a/PIA VPN/th.lproj/Localizable.strings b/PIA VPN/th.lproj/Localizable.strings index 266b7c0b6..e4f396f7b 100644 --- a/PIA VPN/th.lproj/Localizable.strings +++ b/PIA VPN/th.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "การต่ออายุ"; "expiration.message" = "สถานะสมาชิกของคุณจะหมดอายุเร็วๆนี้ ต่ออายุเพื่อรับการป้องกันต่อ"; +"local_notification.non_compliant_wifi.title" = "Wi-Fi ที่ไม่ปลอดภัย: %@"; +"local_notification.non_compliant_wifi.text" = "แตะที่นี่เพื่อรักษาความปลอดภัยให้อุปกรณ์ของคุณ"; + // SHORTCUTS "shortcuts.connect" = "เชื่อมต่อ"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "แผนรายเดือน"; "account.subscriptions.trial" = "แผนทดลองใช้"; "account.unauthorized" = "บางอย่างผิดปกติ โปรดลองลงชื่อเข้าใช้อีกครั้ง"; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "ลบบัญชี"; +"account.delete.alert.title" = "คุณแน่ใจหรือไม่"; +"account.delete.alert.message" = "การลบบัญชี PIA ของคุณจะเป็นการถาวรและไม่สามารถย้อนกลับได้ คุณจะไม่สามารถดึงข้อมูลประจำตัว PIA ของคุณหลังจากดำเนินการนี้ โปรดทราบว่าการดำเนินการนี้จะลบบัญชี PIA ของคุณจากฐานข้อมูลของเราเท่านั้น แต่จะไม่ลบการสมัครใช้งานของคุณ คุณจะต้องไปที่บัญชี Apple ของคุณแล้วยกเลิกการสมัครใช้งาน Private Internet Access จากที่นั่น ไม่เช่นนั้นคุณจะยังคงถูกเรียกเก็บค่าบริการแม้ว่าบัญชี PIA ของคุณจะไม่เปิดใช้งานอีกต่อไป"; +"account.delete.alert.failureMessage" = "เกิดข้อผิดพลาดขณะลบบัญชีของคุณ โปรดลองอีกครั้งในภายหลัง"; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "ธีมที่ใช้งานอยู่"; "settings.application_settings.kill_switch.title" = "ปุ่มตัดการทำงาน VPN"; "settings.application_settings.kill_switch.footer" = "Kill switch ของ VPN จะป้องกันการเข้าถึงอินเทอร์เน็ตหากการเชื่อมต่อ VPN กำลังเชื่อมต่อใหม่ ไม่รวมการตัดการเชื่อมต่อด้วยตนเอง"; +"settings.application_settings.leak_protection.title" = "การป้องกันการรั่วไหล"; +"settings.application_settings.leak_protection.footer" = "iOS มีคุณสมบัติที่ออกแบบมาเพื่อทำงานนอก VPN ตามค่าเริ่มต้น เช่น AirDrop, CarPlay, AirPlay และฮอตสปอตส่วนบุคคล การเปิดใช้งานการปกป้องการรั่วไหลแบบกำหนดเองจะนำทางการรับส่งข้อมูลเหล่านี้ผ่าน VPN แต่อาจส่งผลกระทบต่อวิธีการทำงานของคุณสมบัติดังกล่าว ข้อมูลเพิ่มเติม"; +"settings.application_settings.leak_protection.more_info" = "ข้อมูลเพิ่มเติม"; +"settings.application_settings.allow_local_network.title" = "อนุญาตการเข้าถึงอุปกรณ์บนเครือข่ายท้องถิ่น"; +"settings.application_settings.allow_local_network.footer" = "คงความเชื่อมต่อกับอุปกรณ์ท้องถิ่นอย่างเครื่องพิมพ์หรือเซิร์ฟเวอร์ไฟล์ระหว่างที่เชื่อมต่อกับ VPN (อนุญาตเฉพาะหากคุณไว้ใจผู้คนและอุปกรณ์ในเครือข่ายของคุณ)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™ บล็อกโฆษณา, ตัวติดตาม และมัลแวร์ ในขณะที่คุณกำลังเชื่อมต่อ VPN อยู่"; +"settings.application_settings.leak_protection.alert.title" = "การเปลี่ยนแปลงการตั้งค่า VPN จะมีผลในการเชื่อมต่อครั้งต่อไป"; "settings.content_blocker.title" = "สถานะตัวปิดกั้นเนื้อหา Safari"; "settings.content_blocker.state.title" = "สถานะปัจจุบัน"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "ปุ่มเชื่อมต่อ VPN ขณะนี้ VPN เชื่อมต่ออยู่"; "dashboard.accessibility.vpn.button.isOff" = "ปุ่มเชื่อมต่อ VPN ขณะนี้ VPN ขาดการเชื่อมต่อ"; +"dashboard.vpn.leakprotection.alert.title" = "ตรวจพบ Wi-Fi ที่ไม่ปลอดภัย"; +"dashboard.vpn.leakprotection.alert.message" = "หากต้องการป้องกันการรั่วไหลของข้อมูล ให้แตะ ปิดใช้งานเลย เพื่อปิด “อนุญาตการเข้าถึงอุปกรณ์บนเครือข่ายท้องถิ่น” และเชื่อมต่อใหม่โดยอัตโนมัติ"; +"dashboard.vpn.leakprotection.alert.cta1" = "ปิดใช้งานเลย"; +"dashboard.vpn.leakprotection.alert.cta2" = "เรียนรู้เพิ่มเติม"; +"dashboard.vpn.leakprotection.alert.cta3" = "เพิกเฉย"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "หากต้องการป้องกันการรั่วไหลของข้อมูล ให้แตะ เปลี่ยนเลย เพื่อเปลี่ยนเป็นโปรโตคอล VPN IKEv2 และเชื่อมต่อใหม่โดยอัตโนมัติ"; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "เปลี่ยนเลย"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "เราหวังว่าผลิตภัณฑ์ VPN ของเราจะตอบโจทย์ความต้องการของคุณ"; "rating.problems.question" = "มีอะไรผิดปกติเหรอ"; "rating.problems.subtitle" = "คุณอยากที่จะให้ข้อเสนอแนะไหม เราช่วยปรับปรุงประสบการณ์การใช้งาน PIA ของคุณได้"; -"rating.rate.question" = "รีวิว AppStore เป็นอย่างไร?"; +"rating.review.question" = "รีวิวเราใน AppStore หน่อยไหม?"; +"rating.rate.question" = "ให้คะแนนเราใน AppStore หน่อยไหม?"; "rating.rate.subtitle" = "ขอขอบคุณที่คุณช่วยแชร์ประสบการณ์"; "rating.error.question" = "ไม่สามารถสร้างการเชื่อมต่อได้"; "rating.error.subtitle" = "คุณสามารถลองเลือกภูมิภาคอื่นหรือแจ้งให้เราทราบโดยเปิดทิกเก็ตความช่วยเหลือ"; "rating.error.button.send" = "ส่งความคิดเห็น"; +"rating.alert.button.notreally" = "ไม่ดีกว่า"; +"rating.alert.button.nothanks" = "ไม่ล่ะ ขอบคุณ."; +"rating.alert.button.oksure" = "ได้เลย!"; // CALLING CARDS "card.wireguard.title" = "ลอง WireGuard® ได้แล้ววันนี้!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "IP เฉพาะของคุณเปิดใช้งานสำเร็จแล้ว จะมีอยู่ในรายการการเลือกภูมิภาคของคุณ"; "dedicated.ip.message.expired.token" = "โทเค็นของคุณหมดอายุแล้ว โปรดสร้างใหม่จากหน้าบัญชีของคุณบนเว็บไซต์"; "dedicated.ip.message.error.token" = "โทเค็นของคุณหมดอายุแล้ว โปรดสร้างใหม่จากหน้าบัญชีของคุณบนเว็บไซต์"; +"dedicated.ip.message.error.retryafter" = "มีคำขอเปิดใช้งานโทเค็นที่ล้มเหลวมากเกินไป โปรดลองอีกครั้งหลังเวลาผ่านไป %@ วินาที"; "dedicated.ip.message.token.willexpire" = "IP เฉพาะของคุณจะหมดอายุในไม่ช้า รับใหม่"; "dedicated.ip.message.token.willexpire.link" = "รับใหม่"; "dedicated.ip.message.ip.updated" = "อัปเดต IP เฉพาะของคุณแล้ว"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "แสดงข้อความสื่อสารบริการ"; "inapp.messages.settings.updated" = "อัปเดตการตั้งค่าแล้ว"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "ภูมิภาค"; +"widget.liveActivity.protocol.title" = "โปรโตคอล"; diff --git a/PIA VPN/tr.lproj/Localizable.strings b/PIA VPN/tr.lproj/Localizable.strings index 66f0be472..7a498a6b3 100644 --- a/PIA VPN/tr.lproj/Localizable.strings +++ b/PIA VPN/tr.lproj/Localizable.strings @@ -1,345 +1,440 @@ -"Localizable" = "Yerelleştirilebilir"; -"about.accessibility.component.expand" = "Lisansın tamamını görmek için dokunun"; -"about.app" = "Private Internet Access'ten VPN"; -"about.intro" = "Bu program şu bileşenleri kullanmaktadır:"; -"account.accessibility.eye" = "Göz simgesi"; -"account.accessibility.eye.hint.conceal" = "Şifreyi gizlemek için dokunun"; -"account.accessibility.eye.hint.reveal" = "Şifreyi açmak için dokunun"; -"account.email.caption" = "E-posta"; -"account.email.placeholder" = "E-posta adresi"; -"account.error.unauthorized" = "Kullanıcı adınız ya da şifreniz hatalı."; -"account.expiry_date.expired" = "Planınızın süresi dolmuş."; -"account.expiry_date.information" = "Planınızın süresi %@ tarihinde sona erecek."; -"account.eye.footer" = "Şifrenizi açmak ya da gizlemek için göz simgesine dokunun."; -"account.other.footer" = "Diğer cihazlarınıza Private Internet Access uygulamasını yükleyip yukarıdaki kullanıcı adı ve şifre ile giriş yaparak İnternet'e güvenli şekilde bağlanın."; -"account.password.caption" = "Şifre"; -"account.restore.button" = "Satın alınanı geri yükle"; -"account.restore.description" = "Planınızı yenilemenize rağmen hesabınızdan hâlâ süresinin dolmak üzere olduğu uyarısını alıyorsanız, buradan yenilemeyi baştan başlatabilirsiniz. Bu işlem için sizden para kesilmeyecektir."; -"account.restore.failure.message" = "Yenileme işlemi için geri yüklenebilecek satın alım işlemi bulunamadı."; -"account.restore.failure.title" = "Satın alınanı geri yükle"; -"account.restore.title" = "Hesaba yansıtılmamış satın alma işlemini geri yükleyin"; -"account.reveal.prompt" = "Ortaya çıkarmak için doğrulayın"; -"account.save.item" = "E-postayı güncelle"; -"account.save.prompt" = "Değişiklikleri kaydetmek için doğrulayın"; -"account.save.success" = "E-posta adresiniz kaydedildi."; -"account.set.email.error" = "E-posta adresi eklenirken bir hata oluştu. Lütfen daha sonra tekrar deneyin."; -"account.subscriptions.linkMessage" = "buraya tıklayın."; -"account.subscriptions.message" = "Üyelik ayarlarınızı değiştirmek için buraya tıklayın."; -"account.subscriptions.monthly" = "Aylık plan"; -"account.subscriptions.short.linkMessage" = "Aboneliği yönetin"; -"account.subscriptions.short.message" = "Aboneliği yönetin"; -"account.subscriptions.trial" = "Deneme planı"; -"account.subscriptions.yearly" = "Yıllık plan"; -"account.unauthorized" = "Bir sorun oluştu. Lütfen tekrar giriş yapmayı deneyin"; -"account.update.email.require.password.button" = "Gönder"; -"account.update.email.require.password.message" = "Güvenlik açısından hesabınızda değişiklik yapabilmeniz için PIA şifrenizi girmelisiniz. Devam etmek için lütfen PIA şifrenizi girin."; -"account.update.email.require.password.title" = "PIA Şifresi Gerekli"; -"account.username.caption" = "Kullanıcı Adı"; -"card.wireguard.cta.activate" = "WireGuard®'ı şimdi deneyin"; -"card.wireguard.cta.learn" = "Daha fazla bilgi"; -"card.wireguard.cta.settings" = "Ayarları açın"; -"card.wireguard.description" = "Bu, daha iyi performans, daha düşük CPU kullanımı ve daha uzun pil ömrü sunan, yeni, daha verimli bir VPN protokolü."; -"card.wireguard.title" = "WireGuard®'ı bugün deneyin!"; -"content_blocker.body.footer" = "Lütfen unutmayın: Bu İçerik Engelleyicinin çalışması için VPN bağlantınızın olmasına gerek yoktur ancak yalnızca Safari ile gezindiğinizde çalışacaktır."; -"content_blocker.body.subtitle" = "İçerik Engelleyicimizin Safari ile kullanılmasını etkinleştirmek için lütfen Genel bölümü altından Ayarlar > Safari kısmına gidin ve PIA VPN'de İçerik Engelleyicileri açık hale getirin."; -"content_blocker.title" = "Safari İçerik Engelleyici"; -"dashboard.accessibility.vpn.button" = "VPN Bağlantı düğmesi"; -"dashboard.accessibility.vpn.button.isOff" = "VPN Bağlantı düğmesi. Şu anda VPN'ye bağlı değil"; -"dashboard.accessibility.vpn.button.isOn" = "VPN Bağlantı düğmesi. Şu anda VPN'ye bağlı değil"; -"dashboard.connection.ip.caption" = "HERKESE AÇIK IP"; -"dashboard.connection.ip.unreachable" = "İnternet'e erişilemiyor"; -"dashboard.connection.region.caption" = "MEVCUT BÖLGE"; -"dashboard.connection.region.change" = "BÖLGEYİ DEĞİŞTİR"; -"dashboard.content_blocker.intro.message" = "Bu sürüm, MACE'i Safari İçerik Engelleyicimizle değiştirir.\n\n'Ayarlar' bölümünde bunu işaretleyin."; -"dashboard.status" = "Durum"; -"dashboard.vpn.changing_region" = "Bölge değiştiriliyor..."; -"dashboard.vpn.connected" = "VPN'ye Bağlandı"; -"dashboard.vpn.connecting" = "Bağlanıyor..."; -"dashboard.vpn.disconnect.untrusted" = "Bu güvenilir bir ağ değil. VPN bağlantısını kesmek istediğinizden emin misiniz?"; -"dashboard.vpn.disconnected" = "Bağlantı Kesildi"; -"dashboard.vpn.disconnecting" = "Bağlantı Kesiliyor"; -"dashboard.vpn.on" = "VPN: AÇIK"; -"dedicated.ip.activate.button.title" = "Etkinleştir"; -"dedicated.ip.activation.description" = "Belirtecinizi aşağı yapıştırarak Özel IP'nizi etkinleştirin. Kısa süre önce bir özel IP aldıysanız PIA web sitesine giderek belirteci üretebilirsiniz."; -"dedicated.ip.country.flag.accessibility" = "%@ için ülke bayrağı"; -"dedicated.ip.limit.title" = "Seçeceğiniz bir ülkeden bir özel IP alarak, herhangi bir valığa olan uzak bağlantılarınızı güvence altına alın. Aboneliğiniz süresince bu IP yalnızca ama yalnızca size ait olacak ve veri aktarımlarınızı mümkün olan en güçlü şifrelemeyle koruyacak."; -"dedicated.ip.message.error.token" = "Belirtecinizin süresi dolmuş. Lütfen web sitesindeki Hesap sayfanıza giderek yenisini üretin."; -"dedicated.ip.message.expired.token" = "Belirtecinizin süresi dolmuş. Lütfen web sitesindeki Hesap sayfanıza giderek yenisini üretin."; -"dedicated.ip.message.incorrect.token" = "Lütfen belirteci doğru şekilde girdiğinizden emin olun"; -"dedicated.ip.message.invalid.token" = "Belirteciniz geçersiz. Lütfen belirteci doğru şekilde girdiğinizden emin olun"; -"dedicated.ip.message.ip.updated" = "Özel IP'niz güncellendi"; -"dedicated.ip.message.token.willexpire" = "Özel IP'nizin süresi yakında dolacak. Yenisini alın"; -"dedicated.ip.message.token.willexpire.link" = "Yenisini alın"; -"dedicated.ip.message.valid.token" = "Özel IP'niz başarıyla etkinleştirildi. Bölge seçim listenizde mevcut olacak."; -"dedicated.ip.plural.title" = "Özel IP'leriniz"; -"dedicated.ip.remove" = "Seçilen bölgeyi silmek istediğinizden emin misiniz?"; -"dedicated.ip.title" = "Özel IP"; -"dedicated.ip.token.textfield.accessibility" = "Özel IP belirtecinin yazılacağı metin alanı"; -"dedicated.ip.token.textfield.placeholder" = "Belirtecinizi buraya yapıştırın"; -"expiration.message" = "Üyeliğiniz yakında sona erecek. Koruma altında kalmak için yenileyin."; -"expiration.title" = "Yenileme"; -"friend.referrals.days.acquired" = "Ücretsiz günler alındı"; -"friend.referrals.days.number" = "%d gün"; -"friend.referrals.description.short" = "BİR ARKADAŞINIZI ARAMIZA KATIN. 30 GÜN ÜCRETSİZ KULLANIN."; -"friend.referrals.email.validation" = "Geçersiz e-posta adresi. Lütfen tekrar deneyin."; -"friend.referrals.family.friends.program" = "Aile ve Arkadaş Referans Programı"; -"friend.referrals.friends.family.title" = "Arkadaşlarınız ve aile bireylerinizi aramıza katın. Kaydolan her kişi için her ikinize birden 30'ar gün ücretsiz kullanım hakkı vereceğiz. "; -"friend.referrals.fullName" = "Adı ve soyadı"; -"friend.referrals.invitation.terms" = "Bu daveti göndererek Aile ve Arkadaş Referans Programının tüm şart ve koşullarını kabul ediyorum."; -"friend.referrals.invite.error" = "Davet tekrar gönderilemedi. Daha sonra tekrar deneyin."; -"friend.referrals.invite.success" = "Davet başarıyla gönderildi"; -"friend.referrals.invites.number" = "%d davet gönderdiniz"; -"friend.referrals.invites.sent.title" = "Davetler gönderildi"; -"friend.referrals.pending.invites" = "%d davet bekliyor"; -"friend.referrals.pending.invites.title" = "Bekleyen davet"; -"friend.referrals.privacy.note" = "Gizlilikle ilgili sebeplerden ötürü bekleme süresi 30 günü aşan davetler silinir."; -"friend.referrals.reward.given" = "Ödül verildi"; -"friend.referrals.send.invite" = "Davet gönder"; -"friend.referrals.share.link" = "Benzersiz referans linkinizi paylaşın"; -"friend.referrals.share.link.terms" = "Bu daveti gönderdiğinizde Aile ve Arkadaş Referans Programının tüm şart ve koşullarını kabul etmiş olursunuz."; -"friend.referrals.signedup" = "Kaydolan"; -"friend.referrals.signups.number" = "%d kayıt"; -"friend.referrals.title" = "Arkadaşınızı Aramıza Katın"; -"friend.referrals.view.invites.sent" = "Gönderilen davetleri göster"; -"gdpr.accept.button.title" = "Kabul edip devam et"; -"gdpr.collect.data.description" = "E-posta Adresi sadece hesap yönetimi ve ihlale karşı koruma amaçlarıyla kullanılır.\n\nE-posta adresi; abonelik bilgilerini, ödeme onaylarını, müşteri yazışmalarını ve Private Internet Access promosyonlarını göndermek için kullanılır."; -"gdpr.collect.data.title" = "Topladığımız kişisel bilgiler"; -"global.add" = "Ekle"; -"global.automatic" = "Otomatik"; +// GLOBAL + +"global.ok" = "Tamam"; "global.cancel" = "İptal"; -"global.clear" = "Temizle"; "global.close" = "Kapat"; -"global.copied" = "Panoya kopyalandı"; -"global.copy" = "Kopyala"; -"global.disable" = "Kapat"; -"global.disabled" = "Kapalı"; -"global.edit" = "Düzenle"; -"global.empty" = "Boş"; -"global.enable" = "Aç"; -"global.enabled" = "Açık"; "global.error" = "Hata"; -"global.general.settings" = "Genel Ayarlar"; -"global.no" = "Hayır"; -"global.ok" = "Tamam"; -"global.optional" = "İsteğe bağlı"; -"global.or" = "veya"; -"global.remove" = "Kaldır"; -"global.required" = "Gerekli"; -"global.row.selection" = "Sıra seçimi"; -"global.share" = "Paylaş"; -"global.unreachable" = "İnternet bağlantısı bulunamadı. Lütfen İnternet bağlantınızın olduğunu doğrulayın."; +"global.automatic" = "Otomatik"; +"global.required" = "Required"; +"global.optional" = "Optional"; +"global.clear" = "Temizle"; "global.update" = "Güncelle"; -"global.version" = "Sürüm"; -"global.vpn.settings" = "VPN Ayarları"; +"global.edit" = "Düzenle"; +"global.unreachable" = "No internet connection found. Please confirm that you have an internet connection."; +"global.enabled" = "Etkin"; +"global.disabled" = "Devre Dışı"; +"global.enable" = "Etkinleştir"; +"global.disable" = "Kapat"; +"global.add" = "Ekle"; +"global.remove" = "Kaldır"; +"global.empty" = "Empty"; +"global.copy" = "Kopyala"; +"global.share" = "Share"; +"global.copied" = "Panoya kopyalandı"; "global.yes" = "Evet"; -"hotspothelper.display.name" = "🔒 Bu bağlantıyı güvenlik altına almak için PIA Ayarları kısmından VPN WiFi Korumasını açın."; -"hotspothelper.display.protected.name" = "🔒 PIA VPN WiFi Koruması Açık! Arkanızdayız."; -"inapp.messages.settings.updated" = "Ayarlar güncellendi"; -"inapp.messages.toggle.title" = "Hizmet İletişim Mesajlarını Göster"; +"global.no" = "Hayır"; +"global.or" = "or"; +"global.row.selection" = "Row selection"; +"global.vpn.settings" = "VPN Ayarları"; +"global.general.settings" = "General Settings"; +"global.version" = "Sürüm"; + +// NOTIFICATIONS + +"notifications.disabled.title" = "Notifications disabled"; +"notifications.disabled.message" = "Enable notifications to get a reminder to renew your subscription before it expires."; +"notifications.disabled.settings" = "Ayarlar"; + +"expiration.title" = "Renewal"; +"expiration.message" = "Your subscription expires soon. Renew to stay protected."; + +"local_notification.non_compliant_wifi.title" = "Güvenilmeyen Wi-Fi: %@"; +"local_notification.non_compliant_wifi.text" = "Cihazınızı güvence altına almak için buraya dokunun"; + +// SHORTCUTS + +"shortcuts.connect" = "Bağlan"; +"shortcuts.disconnect" = "bağlantısını sonlandırın"; +"shortcuts.select_region" = "Select a region"; + +// RENEWAL + +"renewal.success.title" = "Thank you"; +"renewal.success.message" = "Your account was successfully renewed."; +"renewal.failure.message" = "Your purchase receipt couldn't be submitted, please retry at a later time."; + +// MENU "menu.accessibility.edit.tile" = "Düzenle"; "menu.accessibility.item" = "Menü"; -"menu.accessibility.logged_as" = "%@ olarak giriş yapıldı"; +"menu.accessibility.logged_as" = "Logged in as %@"; +"menu.expiration.expires_in" = "Subscription expires in"; "menu.expiration.days" = "%d gün"; -"menu.expiration.expires_in" = "Üyeliğin sona erme süresi:"; "menu.expiration.hours" = "%d saat"; "menu.expiration.one_hour" = "bir saat"; -"menu.expiration.upgrade" = "HESABI YÜKSELTİN"; +"menu.expiration.upgrade" = "UPGRADE ACCOUNT"; +"menu.item.region" = "Region selection"; "menu.item.about" = "Hakkında"; "menu.item.account" = "Hesap"; -"menu.item.logout" = "Çıkış yap"; -"menu.item.region" = "Bölge seçimi"; "menu.item.settings" = "Ayarlar"; -"menu.item.web.home" = "Ana sayfa"; -"menu.item.web.privacy" = "Gizlilik politikası"; +"menu.item.logout" = "Çıkış yap"; +"menu.item.web.privacy" = "Privacy policy"; +"menu.item.web.home" = "Home page"; "menu.item.web.support" = "Destek"; -"menu.logout.confirm" = "Çıkış yap"; -"menu.logout.message" = "Çıkış yaptığınızda VPN devre dışı kalacak ve korunmasız olacaksınız."; + "menu.logout.title" = "Çıkış yap"; -"menu.renewal.message.trial" = "Deneme hesabı yenilenemez. Hizmeti kullanmaya devam etmek için süresi dolduktan sonra lütfen yeni bir hesap satın alın."; -"menu.renewal.message.unavailable" = "Apple sunucuları şu anda kullanılamıyor. Lütfen daha sonra tekrar deneyin."; -"menu.renewal.message.website" = "Lütfen üyeliğinizi yenilemek için internet sitemizi kullanın."; +"menu.logout.message" = "Logging out will disable the VPN and leave you unprotected."; +"menu.logout.confirm" = "Çıkış yap"; + +"menu.renewal.title" = "Renewal"; "menu.renewal.purchase" = "Satın Al"; "menu.renewal.renew" = "Yenile"; -"menu.renewal.title" = "Yenileme"; -"network.management.tool.add.rule" = "Yeni kural ekle"; -"network.management.tool.alert" = "Otomatik işlev ayarlarınız, mevcut ağ koşulları altında VPN'nin bağlantısını kesik tutacak şekilde yapılandırılmış."; -"network.management.tool.always.connect" = "Daima VPN'ye bağlan"; -"network.management.tool.always.disconnect" = "Daima VPN bağlantısını kes"; -"network.management.tool.choose.wifi" = "Yeni kural eklemek için bir WiFi ağı seçin. "; -"network.management.tool.disable" = "Otomasyonu Kapat"; -"network.management.tool.enable.automation" = "Otomasyonu Etkinleştir"; -"network.management.tool.mobile.data" = "Mobil veri"; -"network.management.tool.open.wifi" = "Ortak WiFi"; -"network.management.tool.retain.state" = "VPN Durumunu Koru"; -"network.management.tool.secure.wifi" = "Güvenli VPN"; -"network.management.tool.title" = "Otomasyonu Yönet"; -"notifications.disabled.message" = "Aboneliğinizi süresi dolmadan önce yenilemek için bildirimleri etkinleştirerek bir hatırlatıcı alın."; -"notifications.disabled.settings" = "Ayarlar"; -"notifications.disabled.title" = "Bildirimler kapalı"; -"rating.enjoy.question" = "PIA VPN hoşunuza gidiyor mu?"; -"rating.enjoy.subtitle" = "Umarız VPN ürünümüz beklentilerinizi karşılıyordur"; -"rating.error.button.send" = "Geri bildirim gönder"; -"rating.error.question" = "Bağlantı kurulamadı"; -"rating.error.subtitle" = "Farklı bir bölge seçebilir ya da bir destek bileti açarak bize bilgi verebilirsiniz."; -"rating.problems.question" = "Sorun nedir?"; -"rating.problems.subtitle" = "Geri bildirim göndermek ister misiniz? PIA kullanırken yaşadığınız deneyimi geliştirmenize yardımcı olabiliriz"; -"rating.rate.question" = "AppStore değerlendirmesi verebilir misiniz?"; -"rating.rate.subtitle" = "Deneyiminizi paylaşmanız bizi memnun eder"; -"region.accessibility.favorite" = "Favori bölge ekleyin"; -"region.accessibility.filter" = "Filtre"; -"region.accessibility.unfavorite" = "Bir favori bölgeyi kaldırın"; -"region.filter.favorites" = "Favoriler"; -"region.filter.latency" = "Gecikme"; -"region.filter.name" = "Ad"; -"region.filter.sortby" = "Bölgeleri sıralama kıstası:"; -"region.search.placeholder" = "Bir bölge arayın"; -"renewal.failure.message" = "Satın alım işleminizin faturası gönderilemedi; lütfen daha sonra tekrar deneyin."; -"renewal.success.message" = "Hesabınız başarıyla yenilendi."; -"renewal.success.title" = "Teşekkürler"; -"server.reconnection.please.wait" = "Lütfen bekleyin..."; -"server.reconnection.still.connection" = "Bağlanma işlemi devam ediyor..."; -"set.email.error.validation" = "Bir e-posta adresi girmeniz gerekiyor."; -"set.email.form.email" = "E-posta adresinizi girin"; -"set.email.password.caption" = "Şifre"; -"set.email.success.message_format" = "Hesap kullanıcı adınızı ve şifrenizi %@ adresinize gönderdik"; -"set.email.why" = "Kullanıcı adınızla şifrenizi gönderebilmemiz için e-posta adresinize ihtiyacımız var."; -"settings.application_information.debug.empty.message" = "Hata ayıklama bilgileri boş; lütfen tekrar göndermeyi denemeden önce bir bağlantı kurun."; -"settings.application_information.debug.empty.title" = "Boş hata ayıklama bilgisi"; -"settings.application_information.debug.failure.message" = "Hata ayıklama bilgileri gönderilemedi."; -"settings.application_information.debug.failure.title" = "Gönderme sırasında hata oluştu"; -"settings.application_information.debug.success.message" = "Hata ayıklama bilgileri başarıyla gönderildi.\nKimlik: %@\nLütfen bu kimliği not edin; destek ekibimiz gönderdiğiniz bilgileri bulmak için bu kimliği kullanacaktır."; -"settings.application_information.debug.success.title" = "Hata ayıklama bilgileri gönderildi"; -"settings.application_information.debug.title" = "Hata Ayıklamayı destek birimine gönderin"; -"settings.application_information.title" = "UYGULAMA BİLGİLERİ"; -"settings.application_settings.active_theme.title" = "Aktif tema"; -"settings.application_settings.dark_theme.title" = "Koyu tema"; -"settings.application_settings.kill_switch.footer" = "VPN kill switch, VPN bağlantısı kesilip yeniden bağlanmaya çalışırken İnternet bağlantısını devre dışı bırakır. Bağlantının elle kesildiği durumlar hariç."; -"settings.application_settings.kill_switch.title" = "VPN Sonlandırma Anahtarı"; -"settings.application_settings.mace.footer" = "PIA MACE™ VPN'e bağlı iken reklam, iz sürücüler ve kötü amaçlı yazılımları engeller."; -"settings.application_settings.mace.title" = "PIA MACE™"; -"settings.application_settings.title" = "UYGULAMA AYARLARI"; -"settings.cards.history.title" = "Son Haberler"; -"settings.commit.buttons.later" = "Daha Sonra"; -"settings.commit.buttons.reconnect" = "Tekrar Bağlan"; -"settings.commit.messages.must_disconnect" = "Bazı değişikliklerin etki etmesi için VPN'nin tekrar bağlanması gerekmektedir."; -"settings.commit.messages.should_reconnect" = "Değişikliklerin etki etmesi için VPN'yi tekrar bağlayın."; -"settings.connection.remote_port.title" = "Uzaktan Bağlantı Noktası"; -"settings.connection.socket_protocol.title" = "Socket"; +"menu.renewal.message.trial" = "Deneme hesabı yenilenemez. Hizmeti kullanmaya devam etmek için süresi dolduktan sonra lütfen yeni bir hesap satın alın."; +"menu.renewal.message.website" = "Please use our website to renew your subscription."; +"menu.renewal.message.unavailable" = "Apple servers currently unavailable. Please try again later."; + +// ACCOUNT + +"account.email.caption" = "E-posta"; +"account.email.placeholder" = "E-posta adresi"; +"account.username.caption" = "Kullanıcı Adı"; +"account.other.footer" = "Get the Private Internet Access app for your other devices and use the above username and password to login and secure your connection."; +"account.restore.title" = "Restore uncredited purchase"; +"account.restore.description" = "If you renewed your plan but your account still says it's about to expire, you can restart the renewal from here. You will not be charged during this process."; +"account.restore.button" = "RESTORE PURCHASE"; +"account.restore.failure.title" = "Restore purchase"; +"account.restore.failure.message" = "No redeemable purchase was found for renewal."; +"account.save.item" = "E-posta adresini güncelle"; +"account.save.prompt" = "Authenticate to save changes"; +"account.save.success" = "Your email address has been saved."; +"account.reveal.prompt" = "Authenticate to reveal"; +"account.expiry_date.information" = "Your plan will expire on %@."; +"account.expiry_date.expired" = "Your plan has expired."; +"account.update.email.require.password.title" = "PIA Parolası Gerekli"; +"account.update.email.require.password.message" = "Güvenlik nedenleriyle, hesabınızda herhangi bir değişiklik yapmak için PIA parolanızı girmeniz gerekli. Lütfen devam etmek için PIA parolanızı girin."; +"account.update.email.require.password.button" = "Gönder"; +"account.error.unauthorized" = "Your username or password is incorrect."; +"account.subscriptions.message" = "You can manage your subscription from here."; +"account.subscriptions.linkMessage" = "buradan ulaşabilirsiniz"; +"account.set.email.error" = "There was an error adding email. Please try again later."; +"account.subscriptions.short.message" = "Manage subscription"; +"account.subscriptions.short.linkMessage" = "Manage subscription"; +"account.subscriptions.yearly" = "Yearly plan"; +"account.subscriptions.monthly" = "Monthly plan"; +"account.subscriptions.trial" = "Trial plan"; +"account.unauthorized" = "Bir sorun oluştu. Lütfen tekrar oturum açmayı deneyin"; +"account.delete" = "Hesabı Sil"; +"account.delete.alert.title" = "Emin misiniz?"; +"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; +"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; + +// SETTINGS + "settings.connection.title" = "BAĞLANTI"; -"settings.connection.transport.title" = "Nakil"; "settings.connection.vpn_protocol.title" = "Protokol Seçimi"; -"settings.content_blocker.footer" = "İçerik Engelleyiciyi etkinleştirmek veya devre dışı bırakmak için Ayarlar > Safari > İçerik Engelleyici bölümüne gidin ve PIA VPN'i açık hale getirin."; -"settings.content_blocker.refresh.title" = "Engelleme listesini yenile"; -"settings.content_blocker.state.title" = "Mevcut durum"; -"settings.content_blocker.title" = "Safari İçerik Engelleyici durumu"; -"settings.dns.alert.clear.message" = "Bu işlem özel DNS'yi temizler ve varsayılan PIA DNS ayarını uygular."; -"settings.dns.alert.clear.title" = "DNS'yi temizle"; -"settings.dns.alert.create.message" = "PIA DNS harici bir şey kullandığınızda DNS trafiğiniz üçüncü kısımlara açık hale gelebilir ve gizliliğiniz risk altına girebilir."; +"settings.connection.transport.title" = "Taşıma"; +"settings.connection.socket_protocol.title" = "Socket"; +"settings.connection.remote_port.title" = "Uzak Bağlantı Noktası"; + +"settings.encryption.title" = "ŞİFRELEME"; +"settings.encryption.cipher.title" = "Veri Şifrelemesi"; +"settings.encryption.digest.title" = "Veri Kimlik Doğrulama"; +"settings.encryption.handshake.title" = "El sıkışma"; + +"settings.application_settings.title" = "APPLICATION SETTINGS"; +"settings.application_settings.dark_theme.title" = "Dark theme"; +"settings.application_settings.active_theme.title" = "Active theme"; +"settings.application_settings.kill_switch.title" = "VPN Acil Anahtarı"; +"settings.application_settings.kill_switch.footer" = "The VPN kill switch prevents access to the Internet if the VPN connection is reconnecting. This excludes disconnecting manually."; +"settings.application_settings.leak_protection.title" = "Sızıntı Koruması"; +"settings.application_settings.leak_protection.footer" = "iOS, varsayılan olarak VPN dışında çalışacak şekilde tasarlanmış özellikleri içerir. Bunlar AirDrop, CarPlay, AirPlay ve Kişisel Erişim Noktaları gibi özellikleri içerir. Özel sızıntı koruması etkinleştirildiğinde, bu trafiğin VPN üzerinden yönlendirilmesi ancak bu özelliklerin işlevselliğini etkileyebilir. Daha fazla bilgi"; +"settings.application_settings.leak_protection.more_info" = "Daha fazla bilgi"; +"settings.application_settings.allow_local_network.title" = "Yerel ağdaki cihazlara erişim izni ver"; +"settings.application_settings.allow_local_network.footer" = "VPN'e bağlıyken yazıcılar veya dosya sunucuları gibi yerel cihazlara bağlı kalın. (Buna yalnızca ağınızdaki kişilere ve cihazlara güveniyorsanız izin verin.)"; +"settings.application_settings.mace.title" = "PIA MACE™"; +"settings.application_settings.mace.footer" = "PIA MACE™ blocks ads, trackers, and malware while you're connected to the VPN."; +"settings.application_settings.leak_protection.alert.title" = "VPN Ayarlarındaki değişiklikler, bir sonraki bağlantıda etkili olacak"; + +"settings.content_blocker.title" = "Safari Content Blocker state"; +"settings.content_blocker.state.title" = "Current state"; +"settings.content_blocker.refresh.title" = "Refresh block list"; +"settings.content_blocker.footer" = "To enable or disable Content Blocker go to Settings > Safari > Content Blockers and toggle PIA VPN."; + +"settings.application_information.title" = "UYGULAMA BİLGİLERİ"; +"settings.application_information.debug.title" = "Hata Ayıklama Kaydını Destek Ekibine Gönderin"; +"settings.application_information.debug.failure.title" = "Error during submission"; +"settings.application_information.debug.failure.message" = "Debug information could not be submitted."; +"settings.application_information.debug.empty.title" = "Empty debug information"; +"settings.application_information.debug.empty.message" = "Debug information is empty, please attempt a connection before retrying submission."; +"settings.application_information.debug.success.title" = "Hata ayıklama bilgileri gönderildi"; +"settings.application_information.debug.success.message" = "Debug information successfully submitted.\nID: %@\nPlease note this ID, as our support team will require this to locate your submission."; + +"settings.commit.messages.must_disconnect" = "The VPN must reconnect for some changes to take effect."; +"settings.commit.messages.should_reconnect" = "Reconnect the VPN to apply changes."; +"settings.commit.buttons.reconnect" = "Yeniden bağlan"; +"settings.commit.buttons.later" = "Daha sonra"; + +"settings.reset.title" = "RESET"; +"settings.reset.defaults.title" = "Ayarları varsayılanlara sıfırla"; +"settings.reset.defaults.confirm.title" = "Reset settings"; +"settings.reset.defaults.confirm.message" = "Bu işlem uygulama ayarlarını sıfırlayacak. Yapmış olduğunuz bütün değişiklikler kaybolacaktır."; +"settings.reset.defaults.confirm.button" = "Sıfırla"; +"settings.reset.footer" = "This will reset all of the above settings to default."; + +"settings.small.packets.title" = "Küçük Paketler Kullan"; +"settings.small.packets.description" = "Bazı yönlendirici ve mobil ağlarla olan uyumluluğu artırmak için IP paket boyutunu hafif düşürecek."; + +"settings.log.connected.error" = "A VPN connection is required. Please connect to the VPN and retry."; +"settings.log.information" = "Sorunların giderilmesine yardımcı olması için teknik desteğe gönderilebilen hata ayıklama günlüklerini kaydedin."; + +"settings.preview.title" = "Preview"; +"settings.server.network.description" = "Next generation network"; +"settings.server.network.alert" = "The VPN has to be disconnected to change the server network."; + +"settings.geo.servers.description" = "Coğrafi Konum Bölgelerini Göster"; +"settings.cards.history.title" = "Son haberler"; + +"settings.ovpn.migration.footer" = "OpenVPN uygulamamızı güncelliyoruz, daha fazla bilgi için buraya tıklayın"; +"settings.ovpn.migration.footer.link" = "buradan"; + +"settings.section.general" = "Genel"; +"settings.section.protocols" = "Protokoller."; +"settings.section.network" = "AĞ"; +"settings.section.privacyFeatures" = "Privacy Features"; +"settings.section.automation" = "Otomasyon"; +"settings.section.help" = "Yardım"; + +// CONTENT BLOCKER + +"content_blocker.title" = "Safari Content Blocker"; +"content_blocker.body.subtitle" = "To enable our Content Blocker for use with Safari please go to Settings > Safari, and under General touch Content Blockers toggle on PIA VPN."; +"content_blocker.body.footer" = "Please note: You do not need to be connected to the VPN for this Content Blocker to work, but it will only work while browsing with Safari."; + +// ABOUT + +"about.app" = "Private Internet Access'ten VPN"; +"about.intro" = "This program uses the following components:"; +"about.accessibility.component.expand" = "Tap to read full license"; + +// DASHBOARD + +"dashboard.content_blocker.intro.message" = "This version replaces MACE with our Safari Content Blocker.\n\nCheck it out in the 'Settings' section."; + +"dashboard.connection.ip.unreachable" = "Internet unreachable"; + +"dashboard.vpn.disconnected" = "Bağlantı Kesildi"; +"dashboard.vpn.connecting" = "Bağlanıyor..."; +"dashboard.vpn.connected" = "Connected to VPN"; +"dashboard.vpn.on" = "VPN: ON"; +"dashboard.vpn.disconnecting" = "Bağlantı kesiliyor..."; +"dashboard.vpn.changing_region" = "Changing region..."; +"dashboard.vpn.disconnect.untrusted" = "This network is untrusted. Do you really want to disconnect the VPN?"; +"dashboard.accessibility.vpn.button" = "VPN Connection button"; +"dashboard.accessibility.vpn.button.isOn" = "VPN Connection button. The VPN is currently connected"; +"dashboard.accessibility.vpn.button.isOff" = "VPN Connection button. The VPN is currently disconnected"; + +"dashboard.vpn.leakprotection.alert.title" = "Güvenilmeyen Wi-Fi algılandı"; +"dashboard.vpn.leakprotection.alert.message" = "Veri sızıntısını önlemek için, \"Yerel ağdaki cihazlara erişime izin ver\" özelliğini devre dışı bırakmak ve otomatik olarak yeniden bağlanmak için Şimdi Devre Dışı Bırak'a dokunun."; +"dashboard.vpn.leakprotection.alert.cta1" = "Şimdi Kapat"; +"dashboard.vpn.leakprotection.alert.cta2" = "Daha fazlasını öğrenin"; +"dashboard.vpn.leakprotection.alert.cta3" = "Yoksay"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "Veri sızıntısını önlemek için, IKEv2 VPN protokolüne geçmek ve otomatik olarak yeniden bağlanmak için Şimdi Değiştir'e dokunun."; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "Şimdi Değiştir"; + +// VPN PERMISSION + +"vpn_permission.title" = "PIA"; +"vpn_permission.body.title" = "PIA needs access to your VPN profiles to secure your traffic"; +"vpn_permission.body.subtitle" = "You’ll see a prompt for PIA VPN and need to allow access to VPN configurations.\nTo proceed tap on “%@”."; +"vpn_permission.body.footer" = "We don’t monitor, filter or log any network activity."; +"vpn_permission.disallow.message.basic" = "We need this permission for the application to function."; +"vpn_permission.disallow.message.support" = "You can also get in touch with customer support if you need assistance."; +"vpn_permission.disallow.contact" = "İletişim"; + +// CUSTOM DNS + "settings.dns.custom" = "Özel"; +"settings.dns.alert.create.message" = "Using non PIA DNS could expose your DNS traffic to third parties and compromise your privacy."; +"settings.dns.alert.clear.title" = "Clear DNS"; +"settings.dns.alert.clear.message" = "This will clear your custom DNS and default to PIA DNS."; "settings.dns.custom.dns" = "Özel DNS"; "settings.dns.primaryDNS" = "Birincil DNS"; "settings.dns.secondaryDNS" = "İkincil DNS"; +"settings.dns.validation.primary.mandatory" = "Primary DNS is mandatory."; "settings.dns.validation.primary.invalid" = "Birincil DNS geçerli değil."; -"settings.dns.validation.primary.mandatory" = "Birincil DNS boş bırakılamaz."; "settings.dns.validation.secondary.invalid" = "İkincil DNS geçerli değil."; -"settings.encryption.cipher.title" = "Veri Şifreleme"; -"settings.encryption.digest.title" = "Veri Doğrulama"; -"settings.encryption.handshake.title" = "Handshake"; -"settings.encryption.title" = "ŞİFRELEME"; -"settings.geo.servers.description" = "Coğrafi Konum Bölgelerini Göster"; -"settings.hotspothelper.all.description" = "VPN WiFi Koruması, güvenilen ağlar da dâhil olmak üzere tüm ağlarda etkinleşecek."; -"settings.hotspothelper.all.title" = "Tüm ağları koru"; -"settings.hotspothelper.available.add.help" = "Güvenilen ağları eklemek için + simgesine dokunun."; -"settings.hotspothelper.available.help" = "Bu listeyi doldurmak için iOS Ayarları > WiFi kısmına gidin."; -"settings.hotspothelper.cellular.description" = "Bu seçenek etkinleştirildiğinde, PIA, hücresel ağlara bağlanırken VPN'yi otomatik olarak açar."; -"settings.hotspothelper.cellular.networks" = "Hücresel ağlar"; -"settings.hotspothelper.cellular.title" = "Hücresel ağlarda korunun"; -"settings.hotspothelper.description" = "WiFi ağına ya da hücresel ağlara bağlandığınızda PIA'nın nasıl davranacağını yapılandırın. Elle bağlanma durumunda geçerli değildir."; -"settings.hotspothelper.enable.description" = "Bu seçenek açıldığında, PIA, güvenilmeyen WiFi ağlarına bağlandığınızda VPN'yi otomatik olarak açar."; -"settings.hotspothelper.rules.title" = "Kurallar"; -"settings.hotspothelper.title" = "Ağ yönetim aracı"; -"settings.hotspothelper.wifi.networks" = "WiFi ağları"; -"settings.hotspothelper.wifi.trust.title" = "VPN WiFi Koruması"; -"settings.log.connected.error" = "VPN bağlantısı gerekli. Lütfen VPN'ye bağlanıp tekrar deneyin."; -"settings.log.information" = "Sorunların giderilmesine yardımcı olması için, teknik desteğe gönderilebilen hata ayıklama günlüklerini kaydedin."; -"settings.nmt.killswitch.disabled" = "VPN sonlandırma anahtarı şu anda devre dışı. Ağ Yönetim Aracının çalıştığından ve ağ değiştirdiğinizde bağlanabileceğinizden emin olmak için lütfen ayarlarınızdan VPN sonlandırma anahtarını etkinleştirin."; -"settings.nmt.optout.disconnect.alerts" = "Bağlantı kesilmesi onay uyarısını kapat"; -"settings.nmt.optout.disconnect.alerts.description" = "VPN bağlantısı kesilirken gösterilen uyarıyı devre dışı bırakır."; -"settings.nmt.wireguard.warning" = "Farklı ağlar arasında geçiş yaptığınızda WireGuard®'ın tekrar bağlanmasına gerek yoktur. VPN bağlantısını güvenilir ağlarda manuel yoldan kesmeniz gerekebilir."; -"settings.ovpn.migration.footer" = "OpenVPN hizmetinin gerçekleştirilme şeklini güncelliyoruz; daha çok bilgi almak için buraya tıklayın"; -"settings.ovpn.migration.footer.link" = "buraya"; -"settings.preview.title" = "Önizleme"; -"settings.reset.defaults.confirm.button" = "Sıfırla"; -"settings.reset.defaults.confirm.message" = "Bu işlem uygulama ayarlarını sıfırlayacak. Yapmış olduğun bütün değişiklikler kaybolacaktır."; -"settings.reset.defaults.confirm.title" = "Ayarları sıfırla"; -"settings.reset.defaults.title" = "Ayarları varsayılana sıfırla"; -"settings.reset.footer" = "Bu işlem yukarıdaki bütün ayarları sıfırlayarak varsayılan değerlere döndürecektir."; -"settings.reset.title" = "SIFIRLA"; -"settings.section.automation" = "Otomasyon"; -"settings.section.general" = "Genel"; -"settings.section.help" = "Yardım"; -"settings.section.network" = "Ağ"; -"settings.section.privacyFeatures" = "Gizlilik Özellikleri"; -"settings.section.protocols" = "Protokoller"; -"settings.server.network.alert" = "Sunucu ağını değiştirmek için VPN bağlantısının sonlandırılması gerekiyor."; -"settings.server.network.description" = "Yeni nesil ağ"; -"settings.service.quality.share.description" = "VPN bağlantı istatistiklerini paylaşarak gelişmemize yardımcı olun. Bu raporlarda asla kişiyi tanımlayabilecek bilgiler yer almaz."; -"settings.service.quality.share.findoutmore" = "Daha çok bilgi"; -"settings.service.quality.share.title" = "PIA gelişimine yardım edin"; -"settings.service.quality.show.title" = "Bağlantı istatistikleri"; -"settings.small.packets.description" = "Bazı yönlendirici ve mobil ağlarla olan uyumluluğu artırmak için IP paket boyutunu hafif düşürecek."; -"settings.small.packets.title" = "Küçük Paketler Kullanın"; -"settings.trusted.networks.connect.message" = "VPN'ye bağlanarak bu ağı korumak istiyor musunuz?"; -"settings.trusted.networks.message" = "PIA, bu ağlara otomatik olarak bağlanmayacak."; -"settings.trusted.networks.sections.available" = "Mevcut ağlar"; -"settings.trusted.networks.sections.current" = "Mevcut ağ"; -"settings.trusted.networks.sections.trusted" = "Güvenilen ağlar"; -"settings.trusted.networks.sections.trusted.rule.action" = "PIA VPN bağlantısını kes"; -"settings.trusted.networks.sections.trusted.rule.description" = "PIA'nın WiFi ağında ve hücresel ağlarda nasıl davranacağını ayarlamak için VPN sonlandırma anahtarını etkinleştirdikten sonra bu özelliği açın. Bağlantıyı elle sonlandırdığınızda, Ağ Yönetim Aracının işlevselliğinin devre dışı kalacağını lütfen göz önünde bulundurun."; -"settings.trusted.networks.sections.untrusted" = "Güvenilmeyen ağlar"; -"shortcuts.connect" = "Bağlan"; -"shortcuts.disconnect" = "Bağlantıyı Kes"; -"shortcuts.select_region" = "Bir Bölge Seçin"; -"siri.shortcuts.add.error" = "Siri kısayolu eklenirken bir hata meydana geldi. Lütfen tekrar deneyin."; -"siri.shortcuts.connect.row.title" = "'Bağlan' Siri Kısayolu"; -"siri.shortcuts.connect.title" = "PIA VPN'ye bağlan"; -"siri.shortcuts.disconnect.row.title" = "'Bağlantıyı Kes' Siri Kısayolu"; -"siri.shortcuts.disconnect.title" = "PIA VPN bağlantısını kes"; -"tiles.accessibility.invisible.tile.action" = "Bu kısmı panoya eklemek için dokunun"; -"tiles.accessibility.visible.tile.action" = "Bu kısmı panodan kaldırmak için dokunun"; -"tiles.favorite.servers.title" = "Favori sunucular"; -"tiles.nmt.accessibility.trusted" = "Güvenilir ağ"; -"tiles.nmt.accessibility.untrusted" = "Güvenilmeyen ağ"; -"tiles.nmt.cellular" = "Hücresel"; -"tiles.quick.connect.title" = "Hızlı bağlan"; + +// HOTSPOT HELPER + +"settings.hotspothelper.title" = "Network management tool"; +"settings.hotspothelper.description" = "Configure how PIA will behaves on connection to WiFi or cellular networks. This excludes disconnecting manually."; +"settings.hotspothelper.enable.description" = "PIA automatically enables the VPN when connecting to untrusted WiFi networks if this option is enabled."; +"settings.hotspothelper.all.title" = "Protect all networks"; +"settings.hotspothelper.all.description" = "VPN WiFi Protection will activate on all networks, including trusted networks."; +"settings.hotspothelper.available.help" = "To populate this list go to iOS Settings > WiFi."; +"settings.hotspothelper.available.add.help" = "Tap + to add to Trusted networks."; +"settings.trusted.networks.sections.current" = "Current network"; +"settings.trusted.networks.sections.available" = "Available networks"; +"settings.trusted.networks.sections.trusted" = "Trusted networks"; +"settings.trusted.networks.message" = "PIA won't automatically connect on these networks."; +"settings.trusted.networks.connect.message" = "Protect this network by connecting to VPN?"; +"hotspothelper.display.name" = "🔒 Activate VPN WiFi Protection in PIA Settings to secure this connection."; +"hotspothelper.display.protected.name" = "🔒 PIA VPN WiFi Protection Enabled - We got your back."; +"settings.hotspothelper.cellular.title" = "Protect over cellular networks"; +"settings.hotspothelper.wifi.trust.title" = "VPN WiFi Protection"; +"settings.hotspothelper.cellular.description" = "PIA automatically enables the VPN when connecting to cellular networks if this option is enabled."; +"settings.hotspothelper.cellular.networks" = "Cellular networks"; +"settings.hotspothelper.wifi.networks" = "WiFi networks"; +"settings.trusted.networks.sections.untrusted" = "Untrusted networks"; +"settings.hotspothelper.rules.title" = "Rules"; +"settings.trusted.networks.sections.trusted.rule.description" = "Enable this feature, with the VPN kill switch enabled, to customize how PIA will behave on WiFi and cellular networks. Please be aware, functionality of the Network Management Tool will be disabled if you manually disconnect."; +"settings.trusted.networks.sections.trusted.rule.action" = "Disconnect from PIA VPN"; "tiles.quicksetting.nmt.title" = "Ağ Yönetimi"; "tiles.quicksetting.private.browser.title" = "Özel Tarayıcı"; -"tiles.quicksettings.min.elements.message" = "Hızlı Ayarlar Kısmında en az bir unsuru görünür tutmanız gerekiyor"; -"tiles.quicksettings.title" = "Hızlı ayarlar"; +"settings.nmt.killswitch.disabled" = "The VPN kill switch is currently disabled. In order to ensure that the Network Management Tool is functioning, and that you are able to reconnect when switching networks, please enable the VPN kill switch in your settings."; +"settings.nmt.optout.disconnect.alerts" = "Opt-out disconnect confirmation alert"; +"settings.nmt.optout.disconnect.alerts.description" = "Disables the warning alert when disconnecting from the VPN."; +"settings.nmt.wireguard.warning" = "WireGuard® doesn't need to reconnect when you switch between different networks. It may be necessary to manually disconnect the VPN on trusted networks."; +"settings.service.quality.share.title" = "PIA'nın iyileştirilmesine yardım edin"; +"settings.service.quality.share.description" = "VPN bağlantı istatistiklerini bizimle paylaşarak uygulamamızı geliştirmemize yardımcı olun. Bu raporlar hiç bir şekilde kişisel olarak tanımlanabilir bilgiler içermez."; +"settings.service.quality.share.findoutmore" = "Daha çok bilgi"; +"settings.service.quality.show.title" = "Connection stats"; + +"network.management.tool.open.wifi" = "Open WiFi"; +"network.management.tool.secure.wifi" = "Secure WiFi"; +"network.management.tool.mobile.data" = "Mobil veri"; +"network.management.tool.always.connect" = "Her zaman VPN bağlantısı yap"; +"network.management.tool.always.disconnect" = "Her zaman VPN bağlantısını kes"; +"network.management.tool.retain.state" = "Retain VPN State"; +"network.management.tool.add.rule" = "Yeni kural ekle"; +"network.management.tool.choose.wifi" = "Choose a WiFi network to add a new rule. "; +"network.management.tool.title" = "Otomasyonu Yönet"; +"network.management.tool.alert" = "Your automation settings are configured to keep the VPN disconnected under the current network conditions."; +"network.management.tool.disable" = "Disable Automation"; +"network.management.tool.enable.automation" = "Enable Automation"; + +// REGION + +"region.search.placeholder" = "Bir bölge ara"; +"region.accessibility.filter" = "Filter"; +"region.filter.sortby" = "Bölgeleri sırala:"; +"region.filter.name" = "İsim"; +"region.filter.latency" = "Gecikme"; +"region.filter.favorites" = "Favoriler"; +"region.accessibility.favorite" = "Add a favorite region"; +"region.accessibility.unfavorite" = "Remove a favorite region"; + +// TILES +"tiles.quick.connect.title" = "Quick connect"; +"tiles.favorite.servers.title" = "Favorite servers"; "tiles.region.title" = "VPN Sunucusu"; -"tiles.subscription.days.left" = "(%d gün kaldı)"; -"tiles.subscription.monthly" = "Aylık"; "tiles.subscription.title" = "Üyelik"; "tiles.subscription.trial" = "Deneme"; +"tiles.subscription.monthly" = "Aylık"; "tiles.subscription.yearly" = "Yıllık"; +"tiles.subscription.days.left" = "(%d gün kaldı)"; +"tiles.usage.title" = "Usage"; +"tiles.usage.ipsec.title" = "USAGE (Not available on IKEv2)"; +"tiles.usage.upload" = "Yükle"; "tiles.usage.download" = "İndir"; -"tiles.usage.ipsec.title" = "KULLANIM (IKEv2 üzerinde kullanılamaz)"; -"tiles.usage.title" = "Kullanım"; -"tiles.usage.upload" = "Karşıya yükle"; -"today.widget.login" = "Giriş"; -"vpn_permission.body.footer" = "Hiçbir ağ aktivitesini izlemiyor, filtrelemiyor ya da kayıt altına almıyoruz."; -"vpn_permission.body.subtitle" = "PIA VPN için bir açılır pencere göreceksiniz ve VPN yapılandırmalarına erişim izni vermeniz gerekecek.\nDevam etmek için “%@” düğmesine dokunun."; -"vpn_permission.body.title" = "PIA'nın veri trafiğinizi güven altına alabilmesi için VPN yapılandırma ayarlarınıza erişebilmesi gerekmektedir."; -"vpn_permission.disallow.contact" = "İletişim"; -"vpn_permission.disallow.message.basic" = "Uygulamanın çalışabilmesi için bu izne ihtiyaç duymaktayız."; -"vpn_permission.disallow.message.support" = "Yardıma ihtiyacınız olursa, müşteri desteği ile iletişime geçebilirsiniz."; -"vpn_permission.title" = "PIA"; -"walkthrough.action.done" = "BİTTİ"; -"walkthrough.action.next" = "İLERİ"; -"walkthrough.action.skip" = "ATLA"; -"walkthrough.page.1.description" = "Aynı anda 10 cihazda koruma sağlayın."; -"walkthrough.page.1.title" = "Aynı anda 10 cihazı destekler"; -"walkthrough.page.2.description" = "Dünya çapındaki sunucularla daima koruma altındasınız."; -"walkthrough.page.2.title" = "Herhangi bir bölgeye kolayca bağlanın"; -"walkthrough.page.3.description" = "İçerik Engelleyicimizi etkinleştirdiğinizde Safari'de reklamların gösterilmesi engellenir."; -"walkthrough.page.3.title" = "Kendinizi reklamlardan koruyun"; +"tiles.nmt.cellular" = "Cellular"; +"tiles.nmt.accessibility.trusted" = "Trusted network"; +"tiles.nmt.accessibility.untrusted" = "Untrusted network"; +"tiles.quicksettings.title" = "Quick settings"; +"tiles.quicksettings.min.elements.message" = "You should keep at least one element visible in the Quick Settings Tile"; +"tiles.accessibility.visible.tile.action" = "Tap to remove this tile from the dashboard"; +"tiles.accessibility.invisible.tile.action" = "Tap to add this tile to the dashboard"; + +//SIRI SHORTCUTS +"siri.shortcuts.connect.row.title" = "'Connect' Siri Shortcut"; +"siri.shortcuts.disconnect.row.title" = "'Disconnect' Siri Shortcut"; +"siri.shortcuts.connect.title" = "Connect PIA VPN"; +"siri.shortcuts.disconnect.title" = "Disconnect PIA VPN"; +"siri.shortcuts.add.error" = "There was an error adding the Siri shortcut. Please, try it again."; + +//TODAY WIDGET +"today.widget.login" = "Giriş Yapın"; + +//FRIEND REFERRALS +"friend.referrals.email.validation" = "Invalid email. Please try again."; +"friend.referrals.title" = "Arkadaş Referansı"; +"friend.referrals.view.invites.sent" = "View invites sent"; +"friend.referrals.pending.invites" = "%d bekleyen davet"; +"friend.referrals.signups.number" = "%d kayıt"; +"friend.referrals.fullName" = "Ad soyad"; +"friend.referrals.invitation.terms" = "By sending this invitation, I agree to all of the terms and conditions of the Family and Friends Referral Program."; +"friend.referrals.family.friends.program" = "Family and Friends Referral Program"; +"friend.referrals.send.invite" = "Send invite"; +"friend.referrals.invite.error" = "Could not resend invite. Try again later."; +"friend.referrals.invite.success" = "Invite sent successfully"; +"friend.referrals.share.link" = "Kişiye özel tavsiye bağlantınızı paylaşın"; +"friend.referrals.share.link.terms" = "By sharing this link, you agree to all of the terms and conditions of the Family and Friends Referral Program."; +"friend.referrals.invites.sent.title" = "Invites sent"; +"friend.referrals.pending.invites.title" = "Bekleyen davet"; +"friend.referrals.invites.number" = "%d davet gönderdiniz"; +"friend.referrals.privacy.note" = "Lütfen unutmayın, gizlilik nedeniyle, 30 günden eski tüm davetler silinir."; +"friend.referrals.signedup" = "Kayıt yaptı"; +"friend.referrals.reward.given" = "Verilen ödül"; +"friend.referrals.days.acquired" = "Alınan ücretsiz günler"; +"friend.referrals.days.number" = "%d gün"; + +"friend.referrals.friends.family.title" = "Arkadaşlarınıza ve aile bireylerinize referans olun. Her kayıtta, hem kaydolan kişi hem de siz 30'ar gün ücretsiz kullanım hakkı alacaksınız. "; +"friend.referrals.description.short" = "BİR ARKADAŞINIZI ARAMIZA KATIN. 30 GÜN ÜCRETSİZ KULLANIM KAZANIN."; + +// GDPR +"gdpr.collect.data.title" = "Personal information we collect"; +"gdpr.collect.data.description" = "E-mail Address for the purposes of account management and protection from abuse.\n\nE-mail address is used to send subscription information, payment confirmations, customer correspondence, and Private Internet Access promotional offers only."; +"gdpr.accept.button.title" = "Agree and continue"; + +// SET EMAIL +"set.email.form.email" = "E-posta adresinizi girin"; +"set.email.why" = "Kullanıcı adınızla parolanızı gönderebilmemiz için e-posta adresinize ihtiyacımız var."; +"set.email.success.message_format" = "We have sent your account username and password at your email address at %@"; +"set.email.password.caption" = "Şifre"; +"set.email.error.validation" = "You must enter an email address."; + +// RATING +"rating.enjoy.question" = "PIA VPN'i beğeniyor musunuz?"; +"rating.enjoy.subtitle" = "Umarız VPN ürünümüz beklentilerinizi karşılıyordur"; +"rating.problems.question" = "Sorun nedir?"; +"rating.problems.subtitle" = "Geri bildirim göndermek ister misiniz? Bu, PIA kullanma deneyiminizi iyileştirmemize yardımcı olabilir"; +"rating.review.question" = "How about an AppStore review?"; +"rating.rate.question" = "How about a rating on the AppStore?"; +"rating.rate.subtitle" = "Deneyiminizi paylaşmanız bizi memnun eder"; +"rating.error.question" = "Bağlantı kurulamadı"; +"rating.error.subtitle" = "Farklı bir bölge seçebilir ya da bir destek bileti açarak bize bilgi verebilirsiniz."; +"rating.error.button.send" = "Send feedback"; +"rating.alert.button.notreally" = "Not Really"; +"rating.alert.button.nothanks" = "No, thanks."; +"rating.alert.button.oksure" = "Ok, sure!"; + +// CALLING CARDS +"card.wireguard.title" = "WireGuard®'ı bugün deneyin!"; +"card.wireguard.description" = "Bu, daha iyi performans, daha düşük CPU kullanımı ve daha uzun pil ömrü sunan, yeni, daha verimli bir VPN protokolü."; +"card.wireguard.cta.activate" = "WireGuard®'ı hemen deneyin"; +"card.wireguard.cta.settings" = "Ayarlar'ı Açın"; +"card.wireguard.cta.learn" = "Daha fazlasını öğrenin"; + +// DEDICATED IP +"dedicated.ip.title" = "Atanmış IP VPN"; +"dedicated.ip.plural.title" = "Your Dedicated IPs"; +"dedicated.ip.activation.description" = "Belirtecinizi aşağıdaki forma yapıştırarak Özel IP'nizi etkinleştirin. Kısa süre önce bir özel IP satın aldıysanız belirteci PIA web sitesine giderek oluşturabilirsiniz."; +"dedicated.ip.token.textfield.placeholder" = "Belirtecinizi buraya yapıştırın"; +"dedicated.ip.token.textfield.accessibility" = "The textfield to type the Dedicated IP token"; +"dedicated.ip.activate.button.title" = "Etkinleştir"; +"dedicated.ip.message.incorrect.token" = "Please make sure you have entered the token correctly"; +"dedicated.ip.message.invalid.token" = "Belirteciniz geçersiz. Lütfen belirteci doğru şekilde girdiğinizden emin olun."; +"dedicated.ip.message.valid.token" = "Özel IP'niz başarıyla etkinleştirildi. Bölge seçim listenizde mevcut olacak."; +"dedicated.ip.message.expired.token" = "Your token is expired. Please generate a new one from your Account page on the website."; +"dedicated.ip.message.error.token" = "Your token is expired. Please generate a new one from your Account page on the website."; +"dedicated.ip.message.error.retryafter" = "Too many failed token activation requests. Please try again after %@ second(s)."; +"dedicated.ip.message.token.willexpire" = "Your dedicated IP will expire soon. Get a new one"; +"dedicated.ip.message.token.willexpire.link" = "Yenisini al"; +"dedicated.ip.message.ip.updated" = "Özel IP'niz güncellendi"; +"dedicated.ip.country.flag.accessibility" = "Country flag for %@"; +"dedicated.ip.remove" = "Are you sure you want to remove the selected region?"; +"dedicated.ip.limit.title" = "Herhangi bir varlıkla olan uzaktan bağlantılarınızı, seçtiğiniz bir ülkeden özel bir IP ile sabitleyin. Aboneliğiniz sırasında bu IP sadece size ait olacak ve veri transferleriniz en güçlü şifrelemeyle koruyacaktır."; + +// RECONNECTIONS +"server.reconnection.please.wait" = "Lütfen bekleyin..."; +"server.reconnection.still.connection" = "Hâlâ bağlanmaya çalışıyor..."; + +// INAPP MESSAGES +"inapp.messages.toggle.title" = "Servis İletişim Mesajlarını Göster"; +"inapp.messages.settings.updated" = "Ayarlar güncellendi"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "Bölge"; +"widget.liveActivity.protocol.title" = "Protokol"; diff --git a/PIA VPN/zh-Hans.lproj/Localizable.strings b/PIA VPN/zh-Hans.lproj/Localizable.strings index af9cca3a7..89aa75b87 100644 --- a/PIA VPN/zh-Hans.lproj/Localizable.strings +++ b/PIA VPN/zh-Hans.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "续订"; "expiration.message" = "您的订阅即将到期。请续期以持续受到保护。"; +"local_notification.non_compliant_wifi.title" = "不安全的 Wi-Fi:%@"; +"local_notification.non_compliant_wifi.text" = "轻点此处以保护您的设备"; + // SHORTCUTS "shortcuts.connect" = "连接"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "包月套餐"; "account.subscriptions.trial" = "试用套餐"; "account.unauthorized" = "出现问题。请尝试重新登录"; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "删除账户"; +"account.delete.alert.title" = "确定?"; +"account.delete.alert.message" = "删除 PIA 账户是永久的、不可挽回的。执行此操作后,您将无法检索自己的 PIA 登录信息。请注意,此操作只会从我们的数据库中删除 PIA 帐户,但不会删除您的订阅。您需要进入苹果账户,从那里取消 Private Internet Access。否则,即使您的 PIA 账户不再有效,您仍将被收取费用。"; +"account.delete.alert.failureMessage" = "删除账户出错,请稍后再试。"; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "活跃主题"; "settings.application_settings.kill_switch.title" = "VPN 切断开关"; "settings.application_settings.kill_switch.footer" = "如果 VPN 连接重新连线,VPN 终止开关会阻止访问互联网。这不包括手动断开连接。"; +"settings.application_settings.leak_protection.title" = "泄露保护"; +"settings.application_settings.leak_protection.footer" = "iOS 包含默认在 VPN 之外运行的功能,例如 AirDrop、CarPlay、AirPlay 和个人热点。启用自定义泄露保护会通过 VPN 路由这些流量,但可能会影响这些功能的运行。更多信息"; +"settings.application_settings.leak_protection.more_info" = "更多信息"; +"settings.application_settings.allow_local_network.title" = "允许访问本地网络上的设备"; +"settings.application_settings.allow_local_network.footer" = "连接到 VPN 时,保持与打印机或文件服务器等本地设备的连接。(仅当您信任网络上的人员和设备时才允许此功能。)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™可在您连接到 VPN 时阻止广告、跟踪和恶意软件。"; +"settings.application_settings.leak_protection.alert.title" = "对 VPN 设置的更改将在下次连接时生效"; "settings.content_blocker.title" = "Safari 内容拦截器状态"; "settings.content_blocker.state.title" = "当前状态"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "VPN 连接按钮。VPN 当前已断开连接"; "dashboard.accessibility.vpn.button.isOff" = "VPN 连接按钮。VPN 当前已断开连接"; +"dashboard.vpn.leakprotection.alert.title" = "检测到不安全的 Wi-Fi"; +"dashboard.vpn.leakprotection.alert.message" = "为防止数据泄露,请轻点“立即停用”以关闭“允许访问本地网络上的设备”并自动重新连接。"; +"dashboard.vpn.leakprotection.alert.cta1" = "立即停用"; +"dashboard.vpn.leakprotection.alert.cta2" = "了解详情"; +"dashboard.vpn.leakprotection.alert.cta3" = "忽略"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "为防止数据泄露,请轻点“立即切换”以更改为 IKEv2 VPN 协议并自动重新连接。"; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "立即切换"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "希望我们的 VPN 产品符合您的期望"; "rating.problems.question" = "出什么问题了?"; "rating.problems.subtitle" = "您希望提供反馈意见吗?我们可以帮助您改善使用 PIA 的体验"; -"rating.rate.question" = "在 AppStore 上发表评论如何?"; +"rating.review.question" = "在 AppStore 上发表评论如何?"; +"rating.rate.question" = "在 AppStore 上评级如何?"; "rating.rate.subtitle" = "感谢您分享使用体验"; "rating.error.question" = "无法建立连接"; "rating.error.subtitle" = "您可以尝试选择其他地区,也可以提交支持请求来告知我们。"; "rating.error.button.send" = "发送反馈"; +"rating.alert.button.notreally" = "不太想"; +"rating.alert.button.nothanks" = "不用,谢谢."; +"rating.alert.button.oksure" = "好的,没问题!"; // CALLING CARDS "card.wireguard.title" = "立即试用 WireGuard®!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "您的专用 IP 已成功激活。您可以在“地区”选择列表中使用该专用 IP。"; "dedicated.ip.message.expired.token" = "您的令牌已过期。请从网站的“账户”页面中生成一个新的令牌。"; "dedicated.ip.message.error.token" = "您的令牌已过期。请从网站的“账户”页面中生成一个新的令牌。"; +"dedicated.ip.message.error.retryafter" = "令牌激活请求失败次数太多。请在 %@ 秒后重试。"; "dedicated.ip.message.token.willexpire" = "您的专用 IP 即将过期。请获取一个新的专用 IP"; "dedicated.ip.message.token.willexpire.link" = "请获取一个新的专用 IP"; "dedicated.ip.message.ip.updated" = "您的专用 IP 已更新"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "显示服务通信消息"; "inapp.messages.settings.updated" = "设置已更新"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "地区"; +"widget.liveActivity.protocol.title" = "协议"; diff --git a/PIA VPN/zh-Hant.lproj/Localizable.strings b/PIA VPN/zh-Hant.lproj/Localizable.strings index 80fe87c0d..48a0d5a27 100644 --- a/PIA VPN/zh-Hant.lproj/Localizable.strings +++ b/PIA VPN/zh-Hant.lproj/Localizable.strings @@ -38,6 +38,9 @@ "expiration.title" = "續訂"; "expiration.message" = "您的訂購計劃即將屆滿,請續約以讓自己繼續獲得保障。"; +"local_notification.non_compliant_wifi.title" = "不安全的 Wi-Fi 網路:%@"; +"local_notification.non_compliant_wifi.text" = "點一下這裡即可保護裝置"; + // SHORTCUTS "shortcuts.connect" = "連線"; @@ -109,10 +112,12 @@ "account.subscriptions.monthly" = "每月方案"; "account.subscriptions.trial" = "試用方案"; "account.unauthorized" = "發生錯誤,請稍後再嘗試登入。"; -"account.delete" = "Delete Account"; -"account.delete.alert.title" = "Are you sure?"; -"account.delete.alert.message" = "Deleting your PIA account is permanent and irreversible. You will not be able to retrieve your PIA credentials after performing this action. Please note that this action only deletes your PIA account from our database, but it does NOT delete your subscription. You will need to go to your Apple account and cancel the Private Internet Access subscription from there. Otherwise, you will still be charged, even though your PIA account will no longer be active."; -"account.delete.alert.failureMessage" = "Something went wrong while deleting your account, please try again later."; +"account.delete" = "刪除帳戶"; +"account.delete.alert.title" = "是否確定?"; +"account.delete.alert.message" = "PIA 帳戶一經刪除即無法還原。一旦執行這個動作,您會無法取回 PIA 憑證。請注意,這個動作只會在資料庫中刪除您的 PIA 帳戶,不會刪除訂購計劃。您必須前往 Apple 帳戶,在那裡取消 Private Internet Access 訂購計劃,否則就算 PIA 帳戶已經停用,您還是會遭到扣款。"; +"account.delete.alert.failureMessage" = "刪除帳戶時發生錯誤,請再試一次。"; +"account.survey.message" = "Want to help make PIA better? Let us know how we can improve!\nTake The Survey"; +"account.survey.messageLink" = "Take The Survey"; // SETTINGS @@ -132,8 +137,14 @@ "settings.application_settings.active_theme.title" = "使用中的主題"; "settings.application_settings.kill_switch.title" = "VPN 切斷開關"; "settings.application_settings.kill_switch.footer" = "如果 VPN 重新連接,VPN 的終止開關將阻止互聯網連線。這不包括手動斷開連接。"; +"settings.application_settings.leak_protection.title" = "防漏"; +"settings.application_settings.leak_protection.footer" = "iOS 內建功能依預設能在 VPN 以外運作,例如 AirDrop、CarPlay、AirPlay 和個人熱點。如果啟用自定防漏功能,就會把這個流量透過 VPN 轉出,但也可能影響這些功能。詳情"; +"settings.application_settings.leak_protection.more_info" = "詳情"; +"settings.application_settings.allow_local_network.title" = "同意取用本機網路上的裝置"; +"settings.application_settings.allow_local_network.footer" = "在連接到 VPN 時繼續連線到本機裝置,例如印表機或檔案伺服器。(只有在您相信網路上的人和裝置時才能同意)"; "settings.application_settings.mace.title" = "PIA MACE™"; "settings.application_settings.mace.footer" = "PIA MACE™ 會在您連線到 VPN 時封鎖廣告、追蹤器及惡意程式。"; +"settings.application_settings.leak_protection.alert.title" = "更改 VPN 設定後,將在下次連線時生效"; "settings.content_blocker.title" = "Safari 內容阻擋器狀態"; "settings.content_blocker.state.title" = "目前狀態"; @@ -213,6 +224,15 @@ "dashboard.accessibility.vpn.button.isOn" = "VPN 連線按鈕。目前已連線至 VPN"; "dashboard.accessibility.vpn.button.isOff" = "VPN 連線按鈕。目前已解除 VPN 連線"; +"dashboard.vpn.leakprotection.alert.title" = "系統偵測到無安全保護的 Wi-Fi 網路"; +"dashboard.vpn.leakprotection.alert.message" = "若要避免資料洩漏,請點一下「立即停用」,以便關掉「同意取用本機網路上的裝置」,然後自動重新連線。"; +"dashboard.vpn.leakprotection.alert.cta1" = "立即停用"; +"dashboard.vpn.leakprotection.alert.cta2" = "更多內容"; +"dashboard.vpn.leakprotection.alert.cta3" = "忽略"; + +"dashboard.vpn.leakprotection.ikev2.alert.message" = "若要避免資料洩漏,請點一下「立即切換」,以便改成 IKEv2 VPN 通訊協定,然後自動重新連線。"; +"dashboard.vpn.leakprotection.ikev2.alert.cta1" = "立即切換"; + // VPN PERMISSION "vpn_permission.title" = "PIA"; @@ -370,11 +390,15 @@ "rating.enjoy.subtitle" = "我們希望我們的 VPN 產品符合您的期望"; "rating.problems.question" = "發生了什麼錯誤?"; "rating.problems.subtitle" = "您想提供反饋嗎?我們可以幫助您改善使用 PIA 的體驗"; -"rating.rate.question" = "可否為我們在 AppStore 評價?"; +"rating.review.question" = "可否為我們在 AppStore 評價?"; +"rating.rate.question" = "幫我們在 App Store 上評分好嗎?"; "rating.rate.subtitle" = "我們非常感謝您分享您的經驗"; "rating.error.question" = "無法建立連線"; "rating.error.subtitle" = "您可嘗試選擇不同區域,或開立支援單來通知我們。"; "rating.error.button.send" = "發送反饋"; +"rating.alert.button.notreally" = "不要"; +"rating.alert.button.nothanks" = "不了,謝謝."; +"rating.alert.button.oksure" = "沒問題!"; // CALLING CARDS "card.wireguard.title" = "立即體驗 WireGuard®!"; @@ -395,6 +419,7 @@ "dedicated.ip.message.valid.token" = "您的專屬 IP 已成功啟用。它將會出現在區域選擇清單中。"; "dedicated.ip.message.expired.token" = "您的權杖已到期。請到網站的帳戶頁面產生新權杖。"; "dedicated.ip.message.error.token" = "您的權杖已到期。請到網站的帳戶頁面產生新權杖。"; +"dedicated.ip.message.error.retryafter" = "權杖啟用要求失敗次數太多。請在 %@ 秒後再試一次。"; "dedicated.ip.message.token.willexpire" = "您的專屬 IP 即將到期。取得新權杖"; "dedicated.ip.message.token.willexpire.link" = "取得新權杖"; "dedicated.ip.message.ip.updated" = "您的專屬 IP 已更新"; @@ -409,3 +434,7 @@ // INAPP MESSAGES "inapp.messages.toggle.title" = "顯示服務通訊訊息"; "inapp.messages.settings.updated" = "已更新設定"; + +// PIA WIDGET +"widget.liveActivity.region.title" = "區域"; +"widget.liveActivity.protocol.title" = "通訊協定"; diff --git a/PIA VPNTests/Core/Utils/PIAHotspotHelperTests.swift b/PIA VPNTests/Core/Utils/PIAHotspotHelperTests.swift index 26140bcbe..cb578b8f4 100644 --- a/PIA VPNTests/Core/Utils/PIAHotspotHelperTests.swift +++ b/PIA VPNTests/Core/Utils/PIAHotspotHelperTests.swift @@ -69,7 +69,7 @@ class PIAHotspotHelperTests: XCTestCase { } func testConfiguration() { - + /* #if arch(i386) || arch(x86_64) XCTAssertTrue(true) #else @@ -87,5 +87,6 @@ class PIAHotspotHelperTests: XCTestCase { response = hotspotHelper.configureHotspotHelper() XCTAssertFalse(response) #endif + */ } } diff --git a/PIA-VPN_E2E_Tests/Core/BaseTest.swift b/PIA-VPN_E2E_Tests/Core/BaseTest.swift new file mode 100644 index 000000000..f47c5fa56 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Core/BaseTest.swift @@ -0,0 +1,41 @@ +// +// BaseTest.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 17/10/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import Quick +import Nimble +import XCTest +import Foundation + +class BaseTest: QuickSpec { + static var app: XCUIApplication! + + override class func spec() { + beforeSuite { + app = XCUIApplication() + app.launch() + if(!app.connectionButton.waitForExistence(timeout: app.defaultTimeout)) { + app.navigateToLoginScreen() + app.logIn(with: CredentialsUtil.credentials(type: .valid)) + app.acceptVPNPermission() + } + } + + beforeEach { + app.launch() + + } + + afterEach { + app.terminate() + } + + afterSuite { + app.terminate() + } + } +} diff --git a/PIA-VPN_E2E_Tests/Helpers/ElementHelper.swift b/PIA-VPN_E2E_Tests/Helpers/ElementHelper.swift new file mode 100644 index 000000000..00471085d --- /dev/null +++ b/PIA-VPN_E2E_Tests/Helpers/ElementHelper.swift @@ -0,0 +1,63 @@ +// +// ElementHelper.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 23/10/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +extension XCUIApplication { + var defaultTimeout: TimeInterval { 10.0 } + var shortTimeout: TimeInterval { 5.0 } + + func navigationBar(with id: String) -> XCUIElement { + return navigationBars[id] + } + + func button(with id: String) -> XCUIElement { + return buttons[id] + } + + func textField(with id: String) -> XCUIElement { + return textFields[id] + } + + func secureTextField(with id: String) -> XCUIElement { + return secureTextFields[id] + } + + func staticText(with id: String) -> XCUIElement{ + return staticTexts[id] + } + + func alert(with id: String) -> XCUIElement{ + return alerts[id] + } + + func otherElement(with id: String) -> XCUIElement { + return otherElements[id] + } + + func cell(with id: String) -> XCUIElement { + return cells[id] + } + + func searchField(with id: String) -> XCUIElement { + return searchFields[id] + } + + func image(with id: String) -> XCUIElement { + return images[id] + } + + func switches(with id: String) -> XCUIElement { + return switches[id] + } + + func dialog(with id: String) -> XCUIElement { + return switches[id] + } +} + diff --git a/PIA-VPN_E2E_Tests/Helpers/WaitHelper.swift b/PIA-VPN_E2E_Tests/Helpers/WaitHelper.swift new file mode 100644 index 000000000..92b5f3fc8 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Helpers/WaitHelper.swift @@ -0,0 +1,55 @@ +// +// WaitHelper.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 24/10/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +enum ElementError: Error, CustomStringConvertible { + case visibilityTimeout + case invisibilityTimeout + + var description: String{ + switch self{ + case .visibilityTimeout: + return "Element visibility check timed out." + case .invisibilityTimeout: + return "Element invisibility check timed out." + } + } +} + +class WaitHelper{ + static var app: XCUIApplication! + + static func waitForElementToBeVisible(_ element:XCUIElement,timeout: TimeInterval = app.defaultTimeout, onSuccess:() -> Void, onFailure:(ElementError) -> Void){ + let predicate = NSPredicate(format:"exists == true") + let expectation = XCTNSPredicateExpectation(predicate: predicate, object: element) + let result = XCTWaiter.wait(for: [expectation], timeout: timeout) + + if result == .completed { + onSuccess() + } + + else { + onFailure(.visibilityTimeout) + } + } + + static func waitForElementToNotBeVisible(_ element:XCUIElement, timeout: TimeInterval = app.defaultTimeout, onSuccess:() -> Void, onFailure:(ElementError) -> Void){ + let predicate = NSPredicate(format:"exists == false") + let expectation = XCTNSPredicateExpectation(predicate: predicate, object: element) + let result = XCTWaiter.wait(for: [expectation], timeout: timeout) + + if result == .completed { + onSuccess() + } + + else { + onFailure(.invisibilityTimeout) + } + } +} diff --git a/PIA-VPN_E2E_Tests/PIA-VPN-e2e-simulator.xctestplan b/PIA-VPN_E2E_Tests/PIA-VPN-e2e-simulator.xctestplan new file mode 100644 index 000000000..8750f1781 --- /dev/null +++ b/PIA-VPN_E2E_Tests/PIA-VPN-e2e-simulator.xctestplan @@ -0,0 +1,40 @@ +{ + "configurations" : [ + { + "id" : "9111258F-C195-402A-BA43-7C730C200FB6", + "name" : "Configuration 1", + "options" : { + + } + } + ], + "defaultOptions" : { + "environmentVariableEntries" : [ + { + "key" : "PIA_TEST_PASSWORD", + "value" : "xxxx" + }, + { + "key" : "PIA_TEST_USER", + "value" : "xyz" + } + ], + "targetForVariableExpansion" : { + "containerPath" : "container:PIA VPN.xcodeproj", + "identifier" : "69B70AAF2ACBF51C0072A09D", + "name" : "PIA-VPN_E2E_Tests" + }, + "testExecutionOrdering" : "random", + "uiTestingScreenshotsLifetime" : "keepNever" + }, + "testTargets" : [ + { + "target" : { + "containerPath" : "container:PIA VPN.xcodeproj", + "identifier" : "69B70AAF2ACBF51C0072A09D", + "name" : "PIA-VPN_E2E_Tests" + } + } + ], + "version" : 1 +} diff --git a/PIA-VPN_E2E_Tests/PIAOnboardingVPNPermissionE2ETests.swift b/PIA-VPN_E2E_Tests/PIAOnboardingVPNPermissionE2ETests.swift new file mode 100644 index 000000000..b765bc7b3 --- /dev/null +++ b/PIA-VPN_E2E_Tests/PIAOnboardingVPNPermissionE2ETests.swift @@ -0,0 +1,112 @@ +// +// PIAOnboardingVPNPermissionE2ETests.swift +// PIA-VPN_E2E_Tests +// +// Created by Laura S on 10/5/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +final class PIAOnboardingVPNPermissionE2ETests: XCTestCase { + + private var app: XCUIApplication! + + override func setUpWithError() throws { + continueAfterFailure = false + app = XCUIApplication(bundleIdentifier: "com.privateinternetaccess.ios.PIA-VPN") + launchAppAndAuthenticate() + } + + override func tearDownWithError() throws { + app.terminate() + } + + private func launchAppAndAuthenticate() { + dismissNotificationsPermissionAlertIfNeeded() + app.launch() + app.logOutIfNeeded() + app.navigateToLoginScreenIfNeeded() + app.fillLoginScreen(with: CredentialsUtil.credentials(type: .valid)) + + guard app.loginButton.exists else { + XCTFail("XCUIApplication: failed to find LOGIN button in screen to authenticate user") + return + } + + app.loginButton.tap() + + guard app.vpnPermissionScreen.waitForExistence(timeout: app.defaultTimeout) else { + XCTFail("XCUIApplication: login failed") + return + } + } + + private func allowVPNProfileInstallationWhenRequested() { + addUIInterruptionMonitor(withDescription: "Vpn permission dialog") { element in + let vpnPermissionAlertText = "“PIA VPN dev” Would Like to Add VPN Configurations" + let isVPNPermissionAlert = element.elementType == .alert && + element.staticTexts[vpnPermissionAlertText].exists + + let allowButton = element.buttons["Allow"].firstMatch + if isVPNPermissionAlert && allowButton.exists { + allowButton.tap() + return true + } else { + return false + } + } + } + + func testAllowVPNProfileInstallation() throws { + let vpnPermissionScreen = app.view(with: AccessibilityId.VPNPermission.screen) + let vpnPermissionButton = app.button(with: AccessibilityId.VPNPermission.submit) + + XCTContext.runActivity(named: "GIVEN that the Vpn Permission screen is shown") { _ in + XCTAssertTrue(vpnPermissionScreen.exists) + XCTAssertTrue(vpnPermissionButton.exists) + } + + XCTContext.runActivity(named: "WHEN giving consent to install the VPN profile") { _ in + allowVPNProfileInstallationWhenRequested() + vpnPermissionButton.tap() + + // Do some action on the app so that the system alert is handled + app.swipeUp() + } + + XCTContext.runActivity(named: "THEN the Home screen is shown") { _ in + let dashboardMenuButtonExists = app.dashboardMenuButton.waitForExistence(timeout: app.defaultTimeout) + + XCTAssertTrue(dashboardMenuButtonExists) + } + + XCTContext.runActivity(named: "AND the VPN Permission screen is NOT shown") { _ in + XCTAssertFalse(app.vpnPermissionScreen.exists) + } + } + +} + +extension PIAOnboardingVPNPermissionE2ETests { + /* Dismisses only the system alert about sending Notifications Permission. + Sometimes this alert appears unexpectedly + when the app launches. + This makes not possible to continue with the test + since the rest of the UI becomes not interactable */ + private func dismissNotificationsPermissionAlertIfNeeded() { + addUIInterruptionMonitor(withDescription: "Notifications permission alert") { element in + let vpnPermissionAlertText = "“PIA VPN dev” Would Like to Send You Notifications" + let isNotificationsPermissionAlert = element.elementType == .alert && + element.staticTexts[vpnPermissionAlertText].exists + + let allowButton = element.buttons["Allow"].firstMatch + if isNotificationsPermissionAlert && allowButton.exists { + allowButton.tap() + return true + } else { + return false + } + } + } +} diff --git a/PIA-VPN_E2E_Tests/PIASignInE2ETests.swift b/PIA-VPN_E2E_Tests/PIASignInE2ETests.swift new file mode 100644 index 000000000..333983297 --- /dev/null +++ b/PIA-VPN_E2E_Tests/PIASignInE2ETests.swift @@ -0,0 +1,72 @@ +// +// PIASignInE2ETests.swift +// PIASignInE2ETests +// +// Created by Laura S on 10/3/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + + +final class PIASignInE2ETests: XCTestCase { + private var app: XCUIApplication! + + override func setUpWithError() throws { + continueAfterFailure = false + app = XCUIApplication() + + // Handles any possible interruption in the test + // due to the appearence of a permission system alert + // (like Notifications permission, VPN profile installation, etc.) + app.dismissAnyPermissionSystemAlert(from: self) + + app.launch() + + app.logOutIfNeeded() + app.navigateToLoginScreenIfNeeded() + } + + override func tearDownWithError() throws { + app.terminate() + } + + func testSignInWithValidCredentials() throws { + XCTContext.runActivity(named: "GIVEN that valid credentials are provided in the login screen") { _ in + app.fillLoginScreen(with: CredentialsUtil.credentials(type: .valid)) + } + + XCTContext.runActivity(named: "WHEN tapping the 'Login' button") { _ in + app.loginButton.tap() + } + + XCTContext.runActivity(named: "THEN the VPN Permission screen will appear") { _ in + XCTAssertTrue(app.vpnPermissionScreen.waitForExistence(timeout: app.defaultTimeout)) + } + + XCTContext.runActivity(named: "AND no login error banner is displayed") { _ in + XCTAssertFalse(app.loginErrorMessage.exists) + } + + } + + func testSignInWithInvalidCredentials() throws { + XCTContext.runActivity(named: "GIVEN that invalid credentials are provided in the login screen") { _ in + app.fillLoginScreen(with: CredentialsUtil.credentials(type: .invalid)) + } + + XCTContext.runActivity(named: "WHEN tapping the 'Login' button") { _ in + app.loginButton.tap() + } + + XCTContext.runActivity(named: "THEN the login error banner is displayed") { _ in + XCTAssertTrue(app.loginErrorMessage.waitForExistence(timeout: app.shortTimeout)) + } + + XCTContext.runActivity(named: "AND the app does NOT display the Vpn Permission Screen") { _ in + XCTAssertFalse(app.vpnPermissionScreen.exists) + } + } + +} + diff --git a/PIA-VPN_E2E_Tests/Screens/Common.swift b/PIA-VPN_E2E_Tests/Screens/Common.swift new file mode 100644 index 000000000..a064ee50e --- /dev/null +++ b/PIA-VPN_E2E_Tests/Screens/Common.swift @@ -0,0 +1,31 @@ +// +// Common.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 24/10/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +extension XCUIApplication { + /// Sometimes a system alert to request permissions about Notifications or VPN profile installation can appear + /// at any time when the app is running + /// This makes not possible to contitnue with the test unless the alert is dismissed + /// This method dismisses any system alert by pressing 'Allow' button + /// It is adviced that we call this method from all the `setUp` method of the tests from the authentication flow + /// For tests where we require the app to be authenticated, + /// use the method `loginAndInstallVPNProfile(from test: XCTestCase)` from the `setUp` method of the `XCTestCase` + func dismissAnyPermissionSystemAlert(from test: XCTestCase) { + test.addUIInterruptionMonitor(withDescription: "Any system permission alert") { element in + + let allowButton = element.buttons["Allow"].firstMatch + if element.elementType == .alert && allowButton.exists { + allowButton.tap() + return true + } else { + return false + } + } + } +} diff --git a/PIA-VPN_E2E_Tests/Screens/HomeScreen.swift b/PIA-VPN_E2E_Tests/Screens/HomeScreen.swift new file mode 100644 index 000000000..684a180fe --- /dev/null +++ b/PIA-VPN_E2E_Tests/Screens/HomeScreen.swift @@ -0,0 +1,109 @@ +// +// DashboardScreen.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 17/10/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +extension XCUIApplication { + var dashboardMenuButton: XCUIElement{ + button(with: PIALibraryAccessibility.Id.Dashboard.menu) + } + + var connectionButton: XCUIElement { + button(with: AccessibilityId.Dashboard.connectionButton) + } + + var confirmationDialogButton: XCUIElement { + button(with: PIALibraryAccessibility.Id.Dialog.destructive) + } + + var quickSettingsButton: XCUIElement { + cell(with: "QuickSettingsTileCollectionViewCell") + } + + var privateBrowserButton: XCUIElement { + button(with: "Private Browser") + } + + var enableNetworkManagementButton: XCUIElement { + button(with: "Enable Network Management") + } + + var disableNetworkManagementButton: XCUIElement { + button(with: "Disable Network Management") + } + + var enableVPNKillSwitchButton: XCUIElement { + button(with: "Enable VPN Kill Switch") + } + + var disableVPNKillSwitchButton: XCUIElement { + button(with: "Disable VPN Kill Switch") + } + + func logOut() { + guard dashboardMenuButton.exists else { return } + dashboardMenuButton.tap() + + if logOutButton.waitForExistence(timeout: defaultTimeout) { + logOutButton.tap() + if confirmationDialogButton.waitForExistence(timeout: shortTimeout) { + confirmationDialogButton.tap() + } + welcomeLoginButton.waitForExistence(timeout: defaultTimeout) + } + } + + func navigateToSettings() { + guard dashboardMenuButton.exists else { return } + dashboardMenuButton.tap() + + if settingsButton.waitForExistence(timeout: defaultTimeout) { + settingsButton.tap() + } + } + + func navigateToHomeFromSettings() { + if settingsBackButton.waitForExistence(timeout: defaultTimeout) { + settingsBackButton.tap() + navigateToHome() + } + } + + func navigateToQuickSettings() { + quickSettingsButton.staticTexts["QUICK SETTINGS"].tap() + } + + func navigateToHome() { + closeButton.tap() + dashboardMenuButton.waitForExistence(timeout: defaultTimeout) + } + + func enableVPNKillSwitchOnHome() { + if(enableVPNKillSwitchButton.exists) { + enableVPNKillSwitchButton.tap() + } + } + + func disableVPNKillSwitchOnHome() { + if(disableVPNKillSwitchButton.exists) { + disableVPNKillSwitchButton.tap() + } + } + + func enableNetworkManagementOnHome() { + if(enableNetworkManagementButton.exists) { + enableNetworkManagementButton.tap() + } + } + + func disableNetworkManagementOnHome() { + if(disableNetworkManagementButton.exists) { + disableNetworkManagementButton.tap() + } + } +} diff --git a/PIA-VPN_E2E_Tests/Screens/LoginScreen.swift b/PIA-VPN_E2E_Tests/Screens/LoginScreen.swift new file mode 100644 index 000000000..408a18fb7 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Screens/LoginScreen.swift @@ -0,0 +1,55 @@ + +import XCTest + +extension XCUIApplication { + var loginButton: XCUIElement { + button(with: PIALibraryAccessibility.Id.Login.submit) + } + + var loginUsernameTextField: XCUIElement { + textField(with: PIALibraryAccessibility.Id.Login.username) + } + + var loginPasswordTextField: XCUIElement { + secureTextField(with: PIALibraryAccessibility.Id.Login.password) + } + + var loginErrorMessage: XCUIElement { + otherElement(with: PIALibraryAccessibility.Id.Login.Error.banner) + } + + func logIn(with credentials: Credentials) { + loginUsernameTextField.waitForExistence(timeout: defaultTimeout) && loginPasswordTextField.waitForExistence(timeout: defaultTimeout) + loginUsernameTextField.tap() + loginUsernameTextField.typeText(credentials.username) + loginPasswordTextField.tap() + loginPasswordTextField.typeText(credentials.password) + loginButton.tap() + } + + /// This method authenticates the user and installs the VPN profile + /// Use this method when we are testing flows where the app has to be logged in already. + /// In such cases, it is recommended to call this method from the `setUp` of each `XCTestCase` class + /// NOTE: the app must be already in the Login Screen for this method to work + /// So before calling this method, make sure to navigate to the login screen + func loginAndInstallVPNProfile(from test: XCTestCase) { + // Listens to any interruption due to a system alert permission + // and presses the 'Allow' button + // (like the VPN Permission system alert) + dismissAnyPermissionSystemAlert(from: test) + + // Log out if needed + logOut() + + navigateToLoginScreen() + logIn(with: CredentialsUtil.credentials(type: .valid)) + + guard vpnPermissionScreen.waitForExistence(timeout: defaultTimeout) else { return } + guard vpnPermissionButton.exists else { return } + vpnPermissionButton.tap() + + swipeUp() + + connectionButton.waitForExistence(timeout: defaultTimeout) + } +} diff --git a/PIA-VPN_E2E_Tests/Screens/Settings/AutomationSettingsScreen.swift b/PIA-VPN_E2E_Tests/Screens/Settings/AutomationSettingsScreen.swift new file mode 100644 index 000000000..641356d25 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Screens/Settings/AutomationSettingsScreen.swift @@ -0,0 +1,28 @@ +// +// AutomationSettingsScreen.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 6/11/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +extension XCUIApplication { + var enableAutomationSwitch: XCUIElement{ + switches(with: "Enable Automation") + } + + func navigateToAutomationSettings() { + guard dashboardMenuButton.exists else { return } + dashboardMenuButton.tap() + + if settingsButton.waitForExistence(timeout: defaultTimeout) { + settingsButton.tap() + } + + if automationSettingsButton.waitForExistence(timeout: defaultTimeout) { + automationSettingsButton.tap() + } + } +} diff --git a/PIA-VPN_E2E_Tests/Screens/Settings/GeneralSettingsScreen.swift b/PIA-VPN_E2E_Tests/Screens/Settings/GeneralSettingsScreen.swift new file mode 100644 index 000000000..cdccdf4f0 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Screens/Settings/GeneralSettingsScreen.swift @@ -0,0 +1,44 @@ +// +// GeneralSettingsScreen.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 2/11/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +extension XCUIApplication { + var connectSiriButton: XCUIElement { + staticText(with: "'Connect' Siri Shortcut") + } + + var disconnectSiriButton: XCUIElement { + staticText(with: "'Disconnect' Siri Shortcut") + } + + var serviceCommMessageSwitch: XCUIElement { + switches(with: "Show Service Communication Messages") + } + + var geoLocatedRegionsSwitch: XCUIElement { + switches(with: "Show Geo-located Regions") + } + + var resetSettingsButton: XCUIElement { + staticText(with: "Reset settings to default") + } + + func navigateToGeneralSettings() { + guard dashboardMenuButton.exists else { return } + dashboardMenuButton.tap() + + if settingsButton.waitForExistence(timeout: defaultTimeout) { + settingsButton.tap() + } + + if generalSettingsButton.waitForExistence(timeout: defaultTimeout) { + generalSettingsButton.tap() + } + } +} diff --git a/PIA-VPN_E2E_Tests/Screens/Settings/HelpSettingsScreen.swift b/PIA-VPN_E2E_Tests/Screens/Settings/HelpSettingsScreen.swift new file mode 100644 index 000000000..d217abf94 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Screens/Settings/HelpSettingsScreen.swift @@ -0,0 +1,36 @@ +// +// HelpSettingsScreen.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 6/11/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +extension XCUIApplication { + var sendDebugButton: XCUIElement { + staticText(with: "Send Debug Log to support") + } + + var helpImprovePIASwitch: XCUIElement { + switches(with: "Help improve PIA") + } + + var latestNewsButton: XCUIElement { + staticText(with: "Latest News") + } + + func navigateToHelpSettings() { + guard dashboardMenuButton.exists else { return } + dashboardMenuButton.tap() + + if settingsButton.waitForExistence(timeout: defaultTimeout) { + settingsButton.tap() + } + + if helpSettingsButton.waitForExistence(timeout: defaultTimeout) { + automationSettingsButton.tap() + } + } +} diff --git a/PIA-VPN_E2E_Tests/Screens/Settings/PrivacySettingsScreen.swift b/PIA-VPN_E2E_Tests/Screens/Settings/PrivacySettingsScreen.swift new file mode 100644 index 000000000..51be69ee4 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Screens/Settings/PrivacySettingsScreen.swift @@ -0,0 +1,36 @@ +// +// PrivacySettingsScreen.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 6/11/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +extension XCUIApplication { + var vpnKillSwitch: XCUIElement { + switches(with: "VPN Kill Switch") + } + + var safariContentBlockerSwitch: XCUIElement { + switches(with: "Safari Content Blocker state") + } + + var refreshBlockListButton: XCUIElement { + staticText(with: "Refresh block list") + } + + func navigateToPrivacySettings() { + guard dashboardMenuButton.exists else { return } + dashboardMenuButton.tap() + + if settingsButton.waitForExistence(timeout: defaultTimeout) { + settingsButton.tap() + } + + if privacySettingsButton.waitForExistence(timeout: defaultTimeout) { + privacySettingsButton.tap() + } + } +} diff --git a/PIA-VPN_E2E_Tests/Screens/Settings/ProtocolsSettingsScreen.swift b/PIA-VPN_E2E_Tests/Screens/Settings/ProtocolsSettingsScreen.swift new file mode 100644 index 000000000..3fcd08a7f --- /dev/null +++ b/PIA-VPN_E2E_Tests/Screens/Settings/ProtocolsSettingsScreen.swift @@ -0,0 +1,48 @@ +// +// ProtocolsSettingsScreen.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 6/11/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +extension XCUIApplication { + var protocolSelectionButton: XCUIElement { + staticText(with: "Protocol Selection") + } + + var dataEncryptionButton: XCUIElement { + staticText(with: "Data Encryption") + } + + var handshakeButton: XCUIElement { + staticText(with: "Handshake") + } + + var useSmallPacketsSwitch: XCUIElement { + switches(with: "User Small Packets") + } + + var openVPN: XCUIElement { + staticText(with: "OpenVPN") + } + + var ipsec: XCUIElement { + staticText(with: "IPSec (IKEv2)") + } + + func navigateToProtocolSettings() { + guard dashboardMenuButton.exists else { return } + dashboardMenuButton.tap() + + if settingsButton.waitForExistence(timeout: defaultTimeout) { + settingsButton.tap() + } + + if protocolsSettingsButton.waitForExistence(timeout: defaultTimeout) { + protocolsSettingsButton.tap() + } + } +} diff --git a/PIA-VPN_E2E_Tests/Screens/Settings/QuickSettingsScreen.swift b/PIA-VPN_E2E_Tests/Screens/Settings/QuickSettingsScreen.swift new file mode 100644 index 000000000..c5c423a46 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Screens/Settings/QuickSettingsScreen.swift @@ -0,0 +1,59 @@ +// +// QuickSettingsScreen.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 15/11/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +extension XCUIApplication { + var vpnKillSwitchQuickSettings: XCUIElement { + cells.containing(.staticText, identifier: "VPN Kill Switch").firstMatch.switches.firstMatch + } + + var networkManagementQuickSettings: XCUIElement { + cells.containing(.staticText, identifier: "Network Management").firstMatch.switches.firstMatch + } + + var privateBrowserQuickSettings: XCUIElement { + cells.containing(.staticText, identifier: "Private Browser").firstMatch.switches.firstMatch + } + + func enableVPNKillSwitchQuickSetting() { + if(vpnKillSwitchQuickSettings.value as! String == "0"){ + vpnKillSwitchQuickSettings.tap() + } + } + + func disableVPNKillSwitchQuickSetting() { + if(vpnKillSwitchQuickSettings.value as! String == "1"){ + vpnKillSwitchQuickSettings.tap() + } + } + + func enableNetworkManagementQuickSetting() { + if(networkManagementQuickSettings.value as! String == "0"){ + networkManagementQuickSettings.tap() + } + } + + func disableNetworkManagementQuickSetting() { + if(networkManagementQuickSettings.value as! String == "1"){ + networkManagementQuickSettings.tap() + } + } + + func enablePrivateBrowserQuickSetting() { + if(privateBrowserQuickSettings.value as! String == "0"){ + privateBrowserQuickSettings.tap() + } + } + + func disablePrivateBrowserQuickSetting() { + if(privateBrowserQuickSettings.value as! String == "1"){ + privateBrowserQuickSettings.tap() + } + } +} diff --git a/PIA-VPN_E2E_Tests/Screens/Settings/SettingsScreen.swift b/PIA-VPN_E2E_Tests/Screens/Settings/SettingsScreen.swift new file mode 100644 index 000000000..4d82a73e4 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Screens/Settings/SettingsScreen.swift @@ -0,0 +1,43 @@ +// +// SettingsScreen.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 1/11/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +extension XCUIApplication { + var generalSettingsButton: XCUIElement { + staticText(with: "General") + } + + var protocolsSettingsButton: XCUIElement { + staticText(with: "Protocols") + } + + var privacySettingsButton: XCUIElement { + staticText(with: "Privacy Features") + } + + var automationSettingsButton: XCUIElement { + staticText(with: "Automation") + } + + var helpSettingsButton: XCUIElement { + staticText(with: "Help") + } + + var developmentSettingsButton: XCUIElement { + staticText(with: "Development") + } + + var closeButton: XCUIElement { + button(with: "Close") + } + + var settingsBackButton: XCUIElement { + button(with: "Settings") + } +} diff --git a/PIA-VPN_E2E_Tests/Screens/SideMenuScreen.swift b/PIA-VPN_E2E_Tests/Screens/SideMenuScreen.swift new file mode 100644 index 000000000..580cd6449 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Screens/SideMenuScreen.swift @@ -0,0 +1,19 @@ +// +// SideMenuScreen.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 14/11/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +extension XCUIApplication { + var logOutButton: XCUIElement { + staticText(with: "Log out") + } + + var settingsButton: XCUIElement { + staticText(with: "Settings") + } +} diff --git a/PIA-VPN_E2E_Tests/Screens/VPNPermissionScreen.swift b/PIA-VPN_E2E_Tests/Screens/VPNPermissionScreen.swift new file mode 100644 index 000000000..936b60388 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Screens/VPNPermissionScreen.swift @@ -0,0 +1,34 @@ +// +// VPNPermissionScreen.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 17/10/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +extension XCUIApplication { + + var vpnPermissionScreen: XCUIElement { + otherElement(with: AccessibilityId.VPNPermission.screen) + } + + var vpnPermissionButton: XCUIElement { + button(with: AccessibilityId.VPNPermission.submit) + } + + var vpnPermissionAlertText: XCUIElement { + alert(with: "PIA VPN dev” Would Like to Add VPN Configurations") + } + + var vpnAllowButton: XCUIElement { + button(with: "Allow").firstMatch + } + + func acceptVPNPermission() { + vpnPermissionScreen.waitForExistence(timeout:defaultTimeout) + vpnPermissionButton.waitForExistence(timeout:defaultTimeout) + vpnPermissionButton.tap() + } +} diff --git a/PIA-VPN_E2E_Tests/Screens/WelcomeScreen.swift b/PIA-VPN_E2E_Tests/Screens/WelcomeScreen.swift new file mode 100644 index 000000000..b02e21827 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Screens/WelcomeScreen.swift @@ -0,0 +1,29 @@ +// +// WelcomeScreen.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 24/10/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +extension XCUIApplication { + var welcomeLoginButton: XCUIElement { + button(with: PIALibraryAccessibility.Id.Login.submitNew) + } + + var welcomeLoginButtonOldVersion: XCUIElement { + button(with: PIALibraryAccessibility.Id.Login.submit) + } + + func navigateToLoginScreen() { + if welcomeLoginButton.waitForExistence(timeout: shortTimeout) { + welcomeLoginButton.tap() + } else { + if welcomeLoginButtonOldVersion.waitForExistence(timeout: shortTimeout) { + welcomeLoginButtonOldVersion.tap() + } + } + } +} diff --git a/PIA-VPN_E2E_Tests/Tests/BaseTest.swift b/PIA-VPN_E2E_Tests/Tests/BaseTest.swift new file mode 100644 index 000000000..933452d64 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Tests/BaseTest.swift @@ -0,0 +1,29 @@ +// +// BaseTest.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 17/10/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import Quick +import Nimble +import XCTest +import Foundation + +class BaseTest: QuickSpec{ + static var app: XCUIApplication! + + override class func spec(){ + beforeEach { + app = XCUIApplication() + app.launch() + app.logOutIfNeeded() + app.navigateToLoginScreenIfNeeded() + } + + afterEach { + app.terminate() + } + } +} diff --git a/PIA-VPN_E2E_Tests/Tests/OnboardingTests.swift b/PIA-VPN_E2E_Tests/Tests/OnboardingTests.swift new file mode 100644 index 000000000..289c3924b --- /dev/null +++ b/PIA-VPN_E2E_Tests/Tests/OnboardingTests.swift @@ -0,0 +1,34 @@ +// +// OnboardingTests.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 17/10/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import Nimble + +class OnboardingTests:BaseTest { + override class func spec() { + super.spec() + + describe("onboarding vpn permission tests") { + context("vpn profile installation permission") { + it("should display the home screen after allowing vpn profile installation"){ + app.logOut() + app.navigateToLoginScreen() + + app.logIn(with: CredentialsUtil.credentials(type: .valid)) + app.acceptVPNPermission() + + app.vpnPermissionAlertText.waitForExistence(timeout: app.defaultTimeout) + app.vpnAllowButton.waitForExistence(timeout: app.defaultTimeout) + app.swipeUp() + + expect(app.dashboardMenuButton.waitForExistence(timeout: app.defaultTimeout)).to(beTrue()) + expect(app.vpnPermissionScreen.exists).to(beFalse()) + } + } + } + } +} diff --git a/PIA-VPN_E2E_Tests/Tests/PIAExampleWithAuthenticatedAppTest.swift b/PIA-VPN_E2E_Tests/Tests/PIAExampleWithAuthenticatedAppTest.swift new file mode 100644 index 000000000..720a33649 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Tests/PIAExampleWithAuthenticatedAppTest.swift @@ -0,0 +1,45 @@ +// +// PIAExampleWithAuthenticatedAppTest.swift +// PIA-VPN_E2E_Tests +// +// Created by Laura S on 10/6/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import XCTest + +/// This is an example of how to setup a XCTestCase +/// with the app on Authenticated state and the VPN Profile installed +/// from the Onboarding flow +final class PIAExampleWithAuthenticatedAppTest: XCTestCase { + private var app: XCUIApplication! + + override func setUpWithError() throws { + continueAfterFailure = false + // 1. Instantiate the app process + app = XCUIApplication(bundleIdentifier: "com.privateinternetaccess.ios.PIA-VPN") + // 2. Launch the app process + app.launch() + + // 3. Authenticates with valid credentials coming from the Environment variables and installs the VPN Profile + app.loginAndInstallVPNProfile(from: self) + + // NOTE: To add valid credentials in the Environment Variables: + // - Select `PIA-VPN_E2E_Tests` schema + // - On the dropdown menu -> Edit Scheme + // - Tap the 'Run' Button from the left side + // - Add correct values on the Env Variables called `PIA_TEST_USER` and `PIA_TEST_PASSWORD` -> IMPORTANT: Do not commit these updates + } + + override func tearDownWithError() throws { + // Terminates the app process everytime a test has finished its execution + app.terminate() + } + + func testExample() throws { + + // Additional test steps here... + } + + +} diff --git a/PIA-VPN_E2E_Tests/Tests/QuickSettingsTests.swift b/PIA-VPN_E2E_Tests/Tests/QuickSettingsTests.swift new file mode 100644 index 000000000..068180f31 --- /dev/null +++ b/PIA-VPN_E2E_Tests/Tests/QuickSettingsTests.swift @@ -0,0 +1,142 @@ +// +// QuickSettingsTests.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 15/11/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import Nimble +import Foundation + +class QuickSettingsTests : BaseTest { + override class func spec() { + let enabledValue = "1" + let disabledValue = "0" + + super.spec() + + describe("quick settings on homescreen tests") { + context("when quick settings items are displayed on homescreen") { + it("should indicate that it's enabled when the user enables it") { + app.navigateToQuickSettings() + app.enableVPNKillSwitchQuickSetting() + app.enableNetworkManagementQuickSetting() + + app.navigateToHome() + + app.enableVPNKillSwitchOnHome() + expect(app.disableVPNKillSwitchButton.exists).to(beTrue()) + + app.enableNetworkManagementOnHome() + expect(app.disableNetworkManagementButton.exists).to(beTrue()) + } + + it("should indicate that it's disabled when the user disables it") { + app.navigateToQuickSettings() + app.enableVPNKillSwitchQuickSetting() + app.enableNetworkManagementQuickSetting() + + app.navigateToHome() + + app.disableVPNKillSwitchOnHome() + expect(app.enableVPNKillSwitchButton.exists).to(beTrue()) + + app.enableVPNKillSwitchOnHome() + app.disableNetworkManagementOnHome() + expect(app.disableVPNKillSwitchButton.exists).to(beTrue()) + } + + it("should display a notification message and not allow enabling the network management when vpn kill switch is disabled") { + app.navigateToQuickSettings() + app.enableVPNKillSwitchQuickSetting() + app.enableNetworkManagementQuickSetting() + + app.navigateToHome() + + app.enableVPNKillSwitchOnHome() + app.disableVPNKillSwitchOnHome() + app.enableNetworkManagementOnHome() + + app.staticText(with: "ENABLE").tap() + expect(app.disableVPNKillSwitchButton.exists).to(beTrue()) + expect(app.disableNetworkManagementButton.exists).to(beTrue()) + + app.disableVPNKillSwitchOnHome() + app.staticText(with: "CLOSE").tap() + expect(app.enableVPNKillSwitchButton.exists).to(beTrue()) + expect(app.enableNetworkManagementButton.exists).to(beTrue()) + } + } + + context("when selecting items to be displayed for Quick Settings") { + it("should not display disabled selection on homescreen") { + app.navigateToQuickSettings() + + app.disableVPNKillSwitchQuickSetting() + expect(app.vpnKillSwitchQuickSettings.value as! String == disabledValue).to(beTrue()) + app.navigateToHome() + expect{ + let enableVPNKillSwitchButtonPresent = app.enableVPNKillSwitchButton.exists + let disableVPNKillSwitchButtonPresent = app.disableVPNKillSwitchButton.exists + return enableVPNKillSwitchButtonPresent || disableVPNKillSwitchButtonPresent + }.to(beFalse()) + + app.navigateToQuickSettings() + app.enableVPNKillSwitchQuickSetting() + expect(app.vpnKillSwitchQuickSettings.value as! String == enabledValue).to(beTrue()) + app.disableNetworkManagementQuickSetting() + expect(app.networkManagementQuickSettings.value as! String == disabledValue).to(beTrue()) + app.navigateToHome() + expect{ + let enableNetworkManagementButtonPresent = app.enableNetworkManagementButton.exists + let disableNetworkManagementButtonPresent = app.disableNetworkManagementButton.exists + return enableNetworkManagementButtonPresent || disableNetworkManagementButtonPresent + }.to(beFalse()) + + app.navigateToQuickSettings() + app.disablePrivateBrowserQuickSetting() + expect(app.privateBrowserQuickSettings.value as! String == disabledValue).to(beTrue()) + app.navigateToHome() + expect(app.privateBrowserButton.exists).to(beFalse()) + + } + + it("should display enabled selection on homescreen") { + app.navigateToQuickSettings() + + app.enableVPNKillSwitchQuickSetting() + expect(app.vpnKillSwitchQuickSettings.value as! String == enabledValue).to(beTrue()) + + app.enableNetworkManagementQuickSetting() + expect(app.networkManagementQuickSettings.value as! String == enabledValue).to(beTrue()) + + app.enablePrivateBrowserQuickSetting() + expect(app.privateBrowserQuickSettings.value as! String == enabledValue).to(beTrue()) + + app.navigateToHome() + expect(app.privateBrowserButton.exists).to(beTrue()) + expect{ + let enableVPNKillSwitchButtonPresent = app.enableVPNKillSwitchButton.exists + let disableVPNKillSwitchButtonPresent = app.disableVPNKillSwitchButton.exists + return enableVPNKillSwitchButtonPresent || disableVPNKillSwitchButtonPresent + }.to(beTrue()) + expect{ + let enableNetworkManagementButtonPresent = app.enableNetworkManagementButton.exists + let disableNetworkManagementButtonPresent = app.disableNetworkManagementButton.exists + return enableNetworkManagementButtonPresent || disableNetworkManagementButtonPresent + }.to(beTrue()) + } + + it("should return a notification message when all selections are being disabled") { + app.navigateToQuickSettings() + + app.disableVPNKillSwitchQuickSetting() + app.disableNetworkManagementQuickSetting() + app.disablePrivateBrowserQuickSetting() + expect(app.staticText(with: "You should keep at least one element visible in the Quick Settings Tile").waitForExistence(timeout: app.defaultTimeout)).to(beTrue()) + } + } + } + } +} diff --git a/PIA-VPN_E2E_Tests/Tests/SignInTests.swift b/PIA-VPN_E2E_Tests/Tests/SignInTests.swift new file mode 100644 index 000000000..919cef87c --- /dev/null +++ b/PIA-VPN_E2E_Tests/Tests/SignInTests.swift @@ -0,0 +1,34 @@ +// +// SignInTests.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 17/10/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import Nimble + +class SignInTests: BaseTest { + override class func spec(){ + super.spec() + + describe("sign in tests") { + context("account validations") { + it("should successfully sign in with valid credentials") { + app.logOut() + app.navigateToLoginScreen() + app.logIn(with: CredentialsUtil.credentials(type: .valid)) + expect(app.vpnPermissionScreen.waitForExistence(timeout:app.defaultTimeout)).to(beTrue()) + } + + it("should display error mesages with invalid credentials") { + app.logOut() + app.navigateToLoginScreen() + app.logIn(with: CredentialsUtil.credentials(type: .invalid)) + expect(app.loginErrorMessage.waitForExistence(timeout: app.shortTimeout)).to(beTrue()) + expect(app.vpnPermissionScreen.waitForExistence(timeout:app.defaultTimeout)).to(beFalse()) + } + } + } + } +} diff --git a/PIA-VPN_E2E_Tests/Tests/UpdateSettingsTests.swift b/PIA-VPN_E2E_Tests/Tests/UpdateSettingsTests.swift new file mode 100644 index 000000000..c72f1f92b --- /dev/null +++ b/PIA-VPN_E2E_Tests/Tests/UpdateSettingsTests.swift @@ -0,0 +1,84 @@ +// +// UpdateSettingsTests.swift +// PIA-VPN_E2E_Tests +// +// Created by Geneva Parayno on 1/11/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import Nimble + +class UpdateSettingsTests : BaseTest { + override class func spec() { + let geoLocatedRegionDefaultValue = "1" + let vpnKillSwitchDefaultValue = "1" + let automationDefaultValue = "0" + + super.spec() + + describe("settings return to default value after logging out") { + context("updated settings for each category") { + it("should revert changes made on general settings to default after logging out and logging back in") { + app.navigateToGeneralSettings() + app.geoLocatedRegionsSwitch.tap() + + // This check is flaky in CI because the switch has a small animation and there is a small amount of delay when the value gets updated after tapping the switch. + // TODO: Enable this check when we disable the animations on E2E tests + // expect((app.geoLocatedRegionsSwitch.value as! String)) != geoLocatedRegionDefaultValue + + app.navigateToHomeFromSettings() + app.logOut() + app.navigateToLoginScreen() + app.logIn(with: CredentialsUtil.credentials(type: .valid)) + app.acceptVPNPermission() + app.navigateToGeneralSettings() + expect((app.geoLocatedRegionsSwitch.value as! String)) == geoLocatedRegionDefaultValue + } + + it("should revert changes made on protocol settings to default after logging out and logging back in") { + app.navigateToProtocolSettings() + app.protocolSelectionButton.tap() + app.openVPN.tap() + expect(app.openVPN.exists).to(beTrue()) + app.navigateToHomeFromSettings() + app.logOut() + app.navigateToLoginScreen() + app.logIn(with: CredentialsUtil.credentials(type: .valid)) + app.acceptVPNPermission() + app.navigateToProtocolSettings() + expect(app.ipsec.exists).to(beTrue()) + } + + it("should revert changes made on privacy features settings to default after logging out and logging back in") { + app.navigateToPrivacySettings() + app.vpnKillSwitch.tap() + expect((app.vpnKillSwitch.value as! String)) != vpnKillSwitchDefaultValue + app.navigateToHomeFromSettings() + app.logOut() + app.navigateToLoginScreen() + app.logIn(with: CredentialsUtil.credentials(type: .valid)) + app.acceptVPNPermission() + app.navigateToPrivacySettings() + expect((app.vpnKillSwitch.value as! String)) == vpnKillSwitchDefaultValue + } + + it("should revert changes made on automation settings to default after logging out and logging back in") { + app.navigateToAutomationSettings() + app.enableAutomationSwitch.tap() + + // This check is flaky in CI because the switch has a small animation and there is a small amount of delay when the value gets updated after tapping the switch. + // TODO: Enable this check when we disable the animations on E2E tests + // expect((app.enableAutomationSwitch.value as! String)) != automationDefaultValue + + app.navigateToHomeFromSettings() + app.logOut() + app.navigateToLoginScreen() + app.logIn(with: CredentialsUtil.credentials(type: .valid)) + app.acceptVPNPermission() + app.navigateToAutomationSettings() + expect((app.enableAutomationSwitch.value as! String)) == automationDefaultValue + } + } + } + } +} diff --git a/PIA-VPN_E2E_Tests/Util/CredentialsUtil.swift b/PIA-VPN_E2E_Tests/Util/CredentialsUtil.swift new file mode 100644 index 000000000..48d744d0e --- /dev/null +++ b/PIA-VPN_E2E_Tests/Util/CredentialsUtil.swift @@ -0,0 +1,32 @@ +// +// CredentialsUtil.swift +// PIA VPN +// +// Created by Waleed Mahmood on 08.03.22. +// Copyright © 2022 Private Internet Access Inc. All rights reserved. +// + +import Foundation + +public enum CredentialsType: String { + case valid = "valid" + case invalid = "invalid" +} + +public struct Credentials: Codable { + let username: String + let password: String +} + +public class CredentialsUtil { + public static func credentials(type: CredentialsType) -> Credentials { + switch type { + case .invalid: + return Credentials(username: "fakeUser", password: "fakePassword123") + case .valid: + let testUser = ProcessInfo.processInfo.environment["PIA_TEST_USER"] ?? "user-not-found" + let testPassword = ProcessInfo.processInfo.environment["PIA_TEST_PASSWORD"] ?? "password-not-found" + return Credentials(username: testUser, password: testPassword) + } + } +} diff --git a/PIA-VPN_E2E_Tests/XCUIApplication+Extensions/XCUIApplication+Global.swift b/PIA-VPN_E2E_Tests/XCUIApplication+Extensions/XCUIApplication+Global.swift new file mode 100644 index 000000000..63b2d6f57 --- /dev/null +++ b/PIA-VPN_E2E_Tests/XCUIApplication+Extensions/XCUIApplication+Global.swift @@ -0,0 +1,169 @@ + +import XCTest + +extension XCUIApplication { + var defaultTimeout: TimeInterval { 10.0 } + var shortTimeout: TimeInterval { 5.0 } + + func view(with id: String) -> XCUIElement { + return otherElements[id] + } + + func button(with id: String) -> XCUIElement { + return buttons[id] + } + + func textField(with id: String) -> XCUIElement { + return textFields[id] + } + + func cell(with id: String) -> XCUIElement { + return cells[id] + } + + func secureTextField(with id: String) -> XCUIElement { + return secureTextFields[id] + } +} + + +extension XCUIApplication { + // This method navigates to the login screen from the Welcome screen + func navigateToLoginScreenIfNeeded() { + if goToLoginScreenButton.waitForExistence(timeout: shortTimeout) { + goToLoginScreenButton.tap() + } else { + if goToLoginScreenButtonOldVersion.waitForExistence(timeout: shortTimeout) { + goToLoginScreenButtonOldVersion.tap() + } + } + } + + + /// This method authenticates the user and installs the VPN profile + /// Use this method when we are testing flows where the app has to be logged in already. + /// In such cases, it is recommended to call this method from the `setUp` of each `XCTestCase` class + /// NOTE: the app must be already in the Login Screen for this method to work + /// So before calling this method, make sure to navigate to the login screen + func loginAndInstallVPNProfile(from test: XCTestCase) { + // Listens to any interruption due to a system alert permission + // and presses the 'Allow' button + // (like the VPN Permission system alert) + dismissAnyPermissionSystemAlert(from: test) + + // Logs Out if needed + logOutIfNeeded() + + // Goes To the Login Screen + navigateToLoginScreenIfNeeded() + + // Fills in valid credentials in the login screen + // The credentials are set in Environment Variables + let credentials = CredentialsUtil.credentials(type: .valid) + + let usernameTextField = textField(with: PIALibraryAccessibility.Id.Login.username) + + let passwordTextField = secureTextField(with: PIALibraryAccessibility.Id.Login.password) + + guard usernameTextField.exists, passwordTextField.exists else { + XCTFail("XCUIApplication: failed to find username and password fields in screen to authenticate user") + return + } + + guard loginButton.exists else { + XCTFail("XCUIApplication: failed to find LOGIN button in screen to authenticate user") + return + } + + // Type username + usernameTextField.tap() + usernameTextField.typeText(credentials.username) + + // Type password + passwordTextField.tap() + passwordTextField.typeText(credentials.password) + + loginButton.tap() + + guard vpnPermissionScreen.waitForExistence(timeout: app.defaultTimeout) else { + XCTFail("XCUIApplication: login failed") + return + } + + let vpnPermissionButton = button(with: AccessibilityId.VPNPermission.submit) + + guard vpnPermissionButton.exists else { + XCTFail("XCUIApplication: can't find the VPN permission submit button") + return + } + + vpnPermissionButton.tap() + + swipeUp() + + let connectionButtonExists = connectionButton.waitForExistence(timeout: defaultTimeout) + XCTAssertTrue(connectionButtonExists) + XCTAssertTrue(connectionButton.isHittable) + } + + + /// Sometimes a system alert to request permissions about Notifications or VPN profile installation can appear + /// at any time when the app is running + /// This makes not possible to contitnue with the test unless the alert is dismissed + /// This method dismisses any system alert by pressing 'Allow' button + /// It is adviced that we call this method from all the `setUp` method of the tests from the authentication flow + /// For tests where we require the app to be authenticated, + /// use the method `loginAndInstallVPNProfile(from test: XCTestCase)` from the `setUp` method of the `XCTestCase` + func dismissAnyPermissionSystemAlert(from test: XCTestCase) { + test.addUIInterruptionMonitor(withDescription: "Any system permission alert") { element in + + let allowButton = element.buttons["Allow"].firstMatch + if element.elementType == .alert && allowButton.exists { + allowButton.tap() + return true + } else { + return false + } + } + } + + // Logs out from the Dashboard screen (Home screen) + // If the app is showing other view, then this flow does not work + func logOutIfNeeded() { + guard dashboardMenuButton.exists else { return } + + dashboardMenuButton.tap() + + let logOutButton = cell(with: PIALibraryAccessibility.Id.Menu.logout).firstMatch + + if logOutButton.waitForExistence(timeout: defaultTimeout) { + logOutButton.tap() + + let confirmationDialogButton = button(with: PIALibraryAccessibility.Id.Dialog.destructive) + + if confirmationDialogButton.waitForExistence(timeout: shortTimeout) { + confirmationDialogButton.tap() + } + + let welcomeScreen = goToLoginScreenButton + + welcomeScreen.waitForExistence(timeout: defaultTimeout) + + } + } + + // This method asumes that the app is already in the login screen + func fillLoginScreen(with credentials: Credentials) { + if loginUsernameTextField.exists && loginPasswordTextField.exists { + // Type username + loginUsernameTextField.tap() + loginUsernameTextField.typeText(credentials.username) + + // Type password + loginPasswordTextField.tap() + loginPasswordTextField.typeText(credentials.password) + } else { + XCTFail("PIASigninE2ETests: Username and Password text fields on LoginViewController are either not identifiable or are moved") + } + } +} diff --git a/PIA-VPN_E2E_Tests/XCUIApplication+Extensions/XCUIApplication+WelcomeScreen.swift b/PIA-VPN_E2E_Tests/XCUIApplication+Extensions/XCUIApplication+WelcomeScreen.swift new file mode 100644 index 000000000..6364b3366 --- /dev/null +++ b/PIA-VPN_E2E_Tests/XCUIApplication+Extensions/XCUIApplication+WelcomeScreen.swift @@ -0,0 +1,22 @@ +// +// XCUIApplication+WelcomeScreen.swift +// PIA-VPN_E2E_Tests +// +// Created by Laura S on 10/5/23. +// Copyright © 2023 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import XCTest + +// MARK: XCUIApplication + Welcome Screen UI elements + +extension XCUIApplication { + var goToLoginScreenButton: XCUIElement { + button(with: PIALibraryAccessibility.Id.Login.submitNew) + } + + var goToLoginScreenButtonOldVersion: XCUIElement { + button(with: PIALibraryAccessibility.Id.Login.submit) + } +} diff --git a/PIAWidget/Assets.xcassets/PIA-logo.imageset/Contents.json b/PIAWidget/Assets.xcassets/PIA-logo.imageset/Contents.json new file mode 100644 index 000000000..02b5d87ae --- /dev/null +++ b/PIAWidget/Assets.xcassets/PIA-logo.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "Group.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/PIAWidget/Assets.xcassets/PIA-logo.imageset/Group.pdf b/PIAWidget/Assets.xcassets/PIA-logo.imageset/Group.pdf new file mode 100644 index 000000000..9936158f2 Binary files /dev/null and b/PIAWidget/Assets.xcassets/PIA-logo.imageset/Group.pdf differ diff --git a/PIAWidget/Assets.xcassets/connected-button.imageset/Contents.json b/PIAWidget/Assets.xcassets/connected-button.imageset/Contents.json new file mode 100644 index 000000000..84d9e024a --- /dev/null +++ b/PIAWidget/Assets.xcassets/connected-button.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "Group 13.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/PIAWidget/Assets.xcassets/connected-button.imageset/Group 13.pdf b/PIAWidget/Assets.xcassets/connected-button.imageset/Group 13.pdf new file mode 100644 index 000000000..af5a88943 Binary files /dev/null and b/PIAWidget/Assets.xcassets/connected-button.imageset/Group 13.pdf differ diff --git a/PIAWidget/Assets.xcassets/connecting-button.imageset/Contents.json b/PIAWidget/Assets.xcassets/connecting-button.imageset/Contents.json new file mode 100644 index 000000000..065a20d84 --- /dev/null +++ b/PIAWidget/Assets.xcassets/connecting-button.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "State=Connecting.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/PIAWidget/Assets.xcassets/connecting-button.imageset/State=Connecting.pdf b/PIAWidget/Assets.xcassets/connecting-button.imageset/State=Connecting.pdf new file mode 100644 index 000000000..c80d3069a Binary files /dev/null and b/PIAWidget/Assets.xcassets/connecting-button.imageset/State=Connecting.pdf differ diff --git a/PIAWidget/Assets.xcassets/disconnected-button.imageset/ButtonDisconnected.pdf b/PIAWidget/Assets.xcassets/disconnected-button.imageset/ButtonDisconnected.pdf new file mode 100644 index 000000000..cfcdb2c48 Binary files /dev/null and b/PIAWidget/Assets.xcassets/disconnected-button.imageset/ButtonDisconnected.pdf differ diff --git a/PIAWidget/Assets.xcassets/disconnected-button.imageset/Contents.json b/PIAWidget/Assets.xcassets/disconnected-button.imageset/Contents.json new file mode 100644 index 000000000..f2933b6fa --- /dev/null +++ b/PIAWidget/Assets.xcassets/disconnected-button.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "ButtonDisconnected.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/PIAWidget/Assets.xcassets/disconnected-cross.imageset/Contents.json b/PIAWidget/Assets.xcassets/disconnected-cross.imageset/Contents.json new file mode 100644 index 000000000..8f0a02cbc --- /dev/null +++ b/PIAWidget/Assets.xcassets/disconnected-cross.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "IconDisconnected.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/PIAWidget/Assets.xcassets/disconnected-cross.imageset/IconDisconnected.pdf b/PIAWidget/Assets.xcassets/disconnected-cross.imageset/IconDisconnected.pdf new file mode 100644 index 000000000..a627c0ed8 Binary files /dev/null and b/PIAWidget/Assets.xcassets/disconnected-cross.imageset/IconDisconnected.pdf differ diff --git a/PIAWidget/Assets.xcassets/green-checkmark.imageset/Contents.json b/PIAWidget/Assets.xcassets/green-checkmark.imageset/Contents.json new file mode 100644 index 000000000..5c2f805eb --- /dev/null +++ b/PIAWidget/Assets.xcassets/green-checkmark.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "Icon.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/PIAWidget/Assets.xcassets/green-checkmark.imageset/Icon.pdf b/PIAWidget/Assets.xcassets/green-checkmark.imageset/Icon.pdf new file mode 100644 index 000000000..bf5bcc075 Binary files /dev/null and b/PIAWidget/Assets.xcassets/green-checkmark.imageset/Icon.pdf differ diff --git a/PIAWidget/Assets.xcassets/ios-widget.imageset/Badge.pdf b/PIAWidget/Assets.xcassets/ios-widget.imageset/Badge.pdf new file mode 100644 index 000000000..10ca08c10 Binary files /dev/null and b/PIAWidget/Assets.xcassets/ios-widget.imageset/Badge.pdf differ diff --git a/PIAWidget/Assets.xcassets/ios-widget.imageset/Contents.json b/PIAWidget/Assets.xcassets/ios-widget.imageset/Contents.json new file mode 100644 index 000000000..c9eb8c559 --- /dev/null +++ b/PIAWidget/Assets.xcassets/ios-widget.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "Badge.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/PIAWidget/Data/Cache/WidgetPersistenceDatasource.swift b/PIAWidget/Data/Cache/WidgetPersistenceDatasource.swift new file mode 100644 index 000000000..5e1bdd1ec --- /dev/null +++ b/PIAWidget/Data/Cache/WidgetPersistenceDatasource.swift @@ -0,0 +1,17 @@ +// +// WidgetPersistenceDatasource.swift +// PIAWidgetExtension +// +// Created by Juan Docal on 2022-09-28. +// Copyright © 2022 Private Internet Access Inc. All rights reserved. +// + +import Foundation + +internal protocol WidgetPersistenceDatasource { + func getIsVPNConnected() -> Bool + func getIsTrustedNetwork() -> Bool + func getVpnProtocol() -> String + func getVpnPort() -> String + func getVpnSocket() -> String +} diff --git a/PIAWidget/WidgetUtils.swift b/PIAWidget/Data/Cache/WidgetUserDefaultsDatasource.swift similarity index 85% rename from PIAWidget/WidgetUtils.swift rename to PIAWidget/Data/Cache/WidgetUserDefaultsDatasource.swift index 90af3576e..0c25e32c0 100644 --- a/PIAWidget/WidgetUtils.swift +++ b/PIAWidget/Data/Cache/WidgetUserDefaultsDatasource.swift @@ -1,5 +1,5 @@ // -// WidgetUtils.swift +// WidgetUserDefaultsDatasource.swift // PIA VPN // // Created by Jose Blaya on 25/09/2020. @@ -21,53 +21,51 @@ import Foundation -public class WidgetUtils { - - private static let appGroup = "group.com.privateinternetaccess" +internal class WidgetUserDefaultsDatasource: WidgetPersistenceDatasource { - static var isVPNConnected: Bool { + private let appGroup = "group.com.privateinternetaccess" + + // MARK: WidgetPersistenceDatasource + + func getIsVPNConnected() -> Bool { var connected = false if let sharedDefaults = UserDefaults(suiteName: appGroup), let status = sharedDefaults.string(forKey: "vpn.status") { - if status == "connected" { connected = true } - } return connected } - - static var isTrustedNetwork: Bool { + + func getIsTrustedNetwork() -> Bool { if let sharedDefaults = UserDefaults(suiteName: appGroup) { return sharedDefaults.bool(forKey: "vpn.widget.trusted.network") } return false } - - static var vpnProtocol: String { + + func getVpnProtocol() -> String { if let sharedDefaults = UserDefaults(suiteName: appGroup), let value = sharedDefaults.string(forKey: "vpn.widget.protocol") { return value } return "--" } - - static var vpnPort: String { + + func getVpnPort() -> String { if let sharedDefaults = UserDefaults(suiteName: appGroup), let value = sharedDefaults.string(forKey: "vpn.widget.port") { return value } return "--" } - - static var vpnSocket: String { + + func getVpnSocket() -> String { if let sharedDefaults = UserDefaults(suiteName: appGroup), let value = sharedDefaults.string(forKey: "vpn.widget.socket") { return value } return "--" } - - } diff --git a/PIAWidget/WidgetContent.swift b/PIAWidget/Data/Model/WidgetInformation.swift similarity index 92% rename from PIAWidget/WidgetContent.swift rename to PIAWidget/Data/Model/WidgetInformation.swift index e15c8f53f..da8c874f3 100644 --- a/PIAWidget/WidgetContent.swift +++ b/PIAWidget/Data/Model/WidgetInformation.swift @@ -1,5 +1,5 @@ // -// WidgetContent.swift +// WidgetInformation.swift // PIA VPN // // Created by Jose Blaya on 24/09/2020. @@ -22,13 +22,10 @@ import Foundation import WidgetKit -struct WidgetContent: Codable, TimelineEntry { - - var date = Date() - +struct WidgetInformation: Codable, TimelineEntry { + var date: Date = Date() let connected: Bool let vpnProtocol: String let vpnPort: String let vpnSocket: String - } diff --git a/PIAWidget/Domain/UI/PIACircleIcon.swift b/PIAWidget/Domain/UI/PIACircleIcon.swift new file mode 100644 index 000000000..628e06a4e --- /dev/null +++ b/PIAWidget/Domain/UI/PIACircleIcon.swift @@ -0,0 +1,26 @@ + +import SwiftUI + +internal struct PIACircleIcon: View { + + internal let size: CGFloat + internal let iconWidth: CGFloat + + init(size: CGFloat) { + self.size = size + self.iconWidth = (size / 2) + } + + var body: some View { + return ZStack { + Circle() + .fill(Color("BorderColor")) + .frame(width: size) + Image("ios-widget") + .resizable() + .frame(width: iconWidth, height: (iconWidth + 3)) + .padding() + } + } +} + diff --git a/PIAWidget/Domain/UI/PIACircleImageView.swift b/PIAWidget/Domain/UI/PIACircleImageView.swift new file mode 100644 index 000000000..486118d7b --- /dev/null +++ b/PIAWidget/Domain/UI/PIACircleImageView.swift @@ -0,0 +1,26 @@ + +import SwiftUI + +internal struct PIACircleImageView: View { + + internal let size: CGFloat + internal let image: String + internal let contentMode: ContentMode + + + init(size: CGFloat, image: String, contentMode: ContentMode = .fit) { + self.size = size + self.image = image + self.contentMode = contentMode + } + + var body: some View { + Image(image) + .resizable() + .aspectRatio(contentMode: contentMode) + .frame(width: size, height: size) + .clipShape(Circle()) + } +} + + diff --git a/PIAWidget/Domain/UI/PIACircleVpnButton.swift b/PIAWidget/Domain/UI/PIACircleVpnButton.swift new file mode 100644 index 000000000..75a08e9d9 --- /dev/null +++ b/PIAWidget/Domain/UI/PIACircleVpnButton.swift @@ -0,0 +1,44 @@ +// +// PIACircleVpnButton.swift +// PIAWidgetExtension +// +// Created by Juan Docal on 2022-09-28. +// Copyright © 2022 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import SwiftUI + +internal struct PIACircleVpnButton: View { + + internal let color: Color + + private let buttonSize: CGFloat = 40.0 + private let strokeWidth: CGFloat = 8.0 + + @State private var outerCircle: CGFloat + @State private var innerCircle: CGFloat + + init(color: Color) { + self.color = color + self.outerCircle = buttonSize + self.innerCircle = buttonSize - strokeWidth + } + + var body: some View { + return Circle() + .strokeBorder(Color("BorderColor"), lineWidth: strokeWidth * 0.75) + .background(Circle() + .strokeBorder(color, lineWidth: strokeWidth) + .background(Image("vpn-button") + .resizable() + .renderingMode(.template) + .foregroundColor(color) + .aspectRatio(contentMode: .fit) + .frame(width: buttonSize, height: buttonSize) + .padding(0.0) + ) + ) + .padding(buttonSize / 2.0) + } +} diff --git a/PIAWidget/Domain/UI/PIAConnectionView.swift b/PIAWidget/Domain/UI/PIAConnectionView.swift new file mode 100644 index 000000000..7cd3ccc95 --- /dev/null +++ b/PIAWidget/Domain/UI/PIAConnectionView.swift @@ -0,0 +1,61 @@ + +import SwiftUI +import WidgetKit + +@available(iOSApplicationExtension 16.1, *) +internal struct PIAConnectionView: View { + + internal let context: ActivityViewContext + internal let showProtocol: Bool + let localizedRegionText = L10n.Localizable.Widget.LiveActivity.Region.title + let localizedProtocolText = L10n.Localizable.Widget.LiveActivity.SelectedProtocol.title + + init(context: ActivityViewContext, showProtocol: Bool = false) { + self.context = context + self.showProtocol = showProtocol + } + + var body: some View { + HStack { + HStack { + PIACircleImageView(size: 24, image: context.state.regionFlag, contentMode: .fill) + VStack(alignment: .leading) { + Text(localizedRegionText) + .font(.caption) + .foregroundColor(.white) + Text(context.state.regionName) + .font(.caption) + .foregroundColor(.white) + .bold() + } + if showProtocol && context.state.connected { + HStack { + Spacer() + PIACircleImageView(size: 24, image: "green-checkmark") + VStack(alignment: .leading) { + Text(localizedProtocolText) + .font(.caption) + .foregroundColor(.white) + Text(context.state.vpnProtocol) + .font(.caption) + .foregroundColor(.white) + .bold() + } + Spacer() + } + } else { + Spacer() + } + + Link(destination: URL(string: "piavpn:connect")!) { + PIACircleImageView( + size: 54, + image: context.state.connected ? "connected-button" : "disconnected-button" + ) + } + } + } + + } +} + diff --git a/PIAWidget/Domain/UI/PIAIconView.swift b/PIAWidget/Domain/UI/PIAIconView.swift new file mode 100644 index 000000000..22c18fabe --- /dev/null +++ b/PIAWidget/Domain/UI/PIAIconView.swift @@ -0,0 +1,31 @@ +// +// PIAIconView.swift +// PIAWidgetExtension +// +// Created by Juan Docal on 2022-09-28. +// Copyright © 2022 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import SwiftUI + +internal struct PIAIconView: View { + + private let iconRotation: CGFloat = -35.0 + private let iconSize: CGFloat + private let padding: CGFloat + + init(iconSize: CGFloat, padding: CGFloat) { + self.iconSize = iconSize + self.padding = padding + } + + var body: some View { + return Image("robot") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: iconSize, height: iconSize, alignment: .center) + .rotationEffect(Angle(degrees: iconRotation)) + .padding(padding) + } +} diff --git a/PIAWidget/Domain/UI/PIAWidgetView.swift b/PIAWidget/Domain/UI/PIAWidgetView.swift new file mode 100644 index 000000000..d1f5b4f04 --- /dev/null +++ b/PIAWidget/Domain/UI/PIAWidgetView.swift @@ -0,0 +1,52 @@ +// +// PIAWidgetView.swift +// PIAWidgetExtension +// +// Created by Juan Docal on 2022-09-28. +// Copyright © 2022 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import SwiftUI + +struct PIAWidgetView : View { + + @Environment(\.widgetFamily) var widgetFamily + + let entry: PIAWidgetProvider.Entry + let widgetPersistenceDatasource: WidgetPersistenceDatasource + + init( + entry: PIAWidgetProvider.Entry, + widgetPersistenceDatasource: WidgetPersistenceDatasource + ) { + self.entry = entry + self.widgetPersistenceDatasource = widgetPersistenceDatasource + } + + var body: some View { + ZStack(alignment: .bottomTrailing) { + let targetIconSize = widgetFamily == .systemMedium ? 100.0 : 50.0 + let targetPadding = widgetFamily == .systemMedium ? -25.0 : -9.0 + PIAIconView(iconSize: targetIconSize, padding: targetPadding) + HStack { + if widgetPersistenceDatasource.getIsTrustedNetwork() { + PIACircleVpnButton(color: Color("TrustedNetworkColor")) + } else { + let targetColor = widgetPersistenceDatasource.getIsVPNConnected() ? "AccentColor" : "RedColor" + PIACircleVpnButton(color: Color(targetColor)) + } + + if widgetFamily == .systemMedium { + PIAWidgetVpnDetailsView( + vpnProtocol: widgetPersistenceDatasource.getVpnProtocol(), + port: widgetPersistenceDatasource.getVpnPort(), + socket: widgetPersistenceDatasource.getVpnSocket() + ) + } + } + + }.widgetURL(URL(string: widgetFamily == .systemMedium ? "piavpn:view" : "piavpn:connect")) + .background(Color("WidgetBackground")) + } +} diff --git a/PIAWidget/Domain/UI/PIAWidgetVpnDetailsView.swift b/PIAWidget/Domain/UI/PIAWidgetVpnDetailsView.swift new file mode 100644 index 000000000..08404b645 --- /dev/null +++ b/PIAWidget/Domain/UI/PIAWidgetVpnDetailsView.swift @@ -0,0 +1,33 @@ +// +// PIAWidgetVpnDetailsView.swift +// PIAWidgetExtension +// +// Created by Juan Docal on 2022-09-28. +// Copyright © 2022 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import SwiftUI + +internal struct PIAWidgetVpnDetailsView: View { + + private let viewTrailingPadding: CGFloat = 40.0 + + internal let vpnProtocol: String + internal let port: String + internal let socket: String + + init(vpnProtocol: String, port: String, socket: String) { + self.vpnProtocol = vpnProtocol + self.port = port + self.socket = socket + } + + var body: some View { + return VStack { + PIAWidgetVpnDetaislRow(iconName: "icon-protocol", text: vpnProtocol) + PIAWidgetVpnDetaislRow(iconName: "icon-port", text: port) + PIAWidgetVpnDetaislRow(iconName: "icon-socket", text: socket) + }.padding(.trailing, viewTrailingPadding) + } +} diff --git a/PIAWidget/Domain/UI/PIAWidgetVpnDetaislRow.swift b/PIAWidget/Domain/UI/PIAWidgetVpnDetaislRow.swift new file mode 100644 index 000000000..4026469e0 --- /dev/null +++ b/PIAWidget/Domain/UI/PIAWidgetVpnDetaislRow.swift @@ -0,0 +1,38 @@ +// +// PIAWidgetVpnDetaislRow.swift +// PIAWidgetExtension +// +// Created by Juan Docal on 2022-09-29. +// Copyright © 2022 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import SwiftUI + +internal struct PIAWidgetVpnDetaislRow: View { + + private let fontSize: CGFloat = 14.0 + private let iconsSize: CGFloat = 25.0 + private let rowSpacing: CGFloat = 0.0 + + internal let iconName: String + internal let text: String + + init(iconName: String, text: String) { + self.iconName = iconName + self.text = text + } + + var body: some View { + HStack(alignment: .center, spacing: rowSpacing) { + Image(iconName) + .resizable() + .frame(width: iconsSize, height: iconsSize, alignment: .leading) + Spacer() + Text(text) + .font(.system(size: fontSize)) + .foregroundColor(Color("FontColor")) + .frame(maxWidth: .infinity, alignment: .leading) + } + } +} diff --git a/PIAWidget/Domain/Widget/PIAConnectionActivityWidget.swift b/PIAWidget/Domain/Widget/PIAConnectionActivityWidget.swift new file mode 100644 index 000000000..5db0fc13f --- /dev/null +++ b/PIAWidget/Domain/Widget/PIAConnectionActivityWidget.swift @@ -0,0 +1,84 @@ + +import WidgetKit +import SwiftUI + +@available(iOSApplicationExtension 16.1, *) +struct PIAConnectionActivityWidget: Widget { + let localizedRegionText = L10n.Localizable.Widget.LiveActivity.Region.title + + var body: some WidgetConfiguration { + ActivityConfiguration(for: PIAConnectionAttributes.self) { context in + // Create the view that appears on the Lock Screen and as a + // banner on the Home Screen of devices that don't support the + // Dynamic Island. + VStack { + HStack(alignment: .bottom, spacing: 4) { + Image("ios-widget") + .resizable() + .frame(width: 16, height: 22) + Image("PIA-logo") + .resizable() + .frame(width: 30, height: 14) + .padding(.bottom, 1) + } + .padding(.bottom) + PIAConnectionView(context: context, showProtocol: true) + .activityBackgroundTint(Color.black.opacity(0.85)) + } + .padding() + + } dynamicIsland: { context in + // Create the views that appear in the Dynamic Island. + DynamicIsland { + // This content will be shown when user expands the island + DynamicIslandExpandedRegion(.leading, priority: 300) { + PIACircleImageView(size: 46, image: context.state.regionFlag, contentMode: .fill) + } + + DynamicIslandExpandedRegion(.trailing, priority: 200) { + Link(destination: URL(string: "piavpn:connect")!) { + PIACircleImageView( + size: 50, + image: context.state.connected ? "connected-button" : "disconnected-button" + ) + + } + } + + DynamicIslandExpandedRegion(.center, priority: 100) { + VStack(alignment: .leading) { + Text(localizedRegionText) + .font(.caption) + .foregroundColor(.white) + .padding(.top, -8) + Text(context.state.regionName) + .font(.caption) + .foregroundColor(.white) + .bold() + } + .frame(minWidth: (UIScreen.main.bounds.size.width * 0.56), alignment: .leading) + .dynamicIsland(verticalPlacement: .belowIfTooWide) + + } + DynamicIslandExpandedRegion(.bottom) { + // Empty + } + } compactLeading: { + // When the island is wider than the display cutout + PIACircleIcon(size: 28.0) + } compactTrailing: { + // When the island is wider than the display cutout + PIACircleImageView( + size: 24, + image: context.state.connected ? "green-checkmark" : "disconnected-cross" + ) + } minimal: { + // This is used when there are multiple activities + PIACircleIcon(size: 28.0) + } + .contentMargins(.leading, 0, for: .compactLeading) + + } + } +} + diff --git a/PIAWidget/Domain/Widget/PIAConnectionLiveActivityManager.swift b/PIAWidget/Domain/Widget/PIAConnectionLiveActivityManager.swift new file mode 100644 index 000000000..2c2994853 --- /dev/null +++ b/PIAWidget/Domain/Widget/PIAConnectionLiveActivityManager.swift @@ -0,0 +1,85 @@ + +import Foundation +import ActivityKit + +public protocol PIAConnectionLiveActivityManagerType { + func startLiveActivity(with state: PIAConnectionAttributes.ContentState) + func endLiveActivities() +} + +@available(iOS 16.2, *) +public final class PIAConnectionLiveActivityManager: PIAConnectionLiveActivityManagerType { + + private var activity: Activity? + private var currentActivityPriority = 0 + + static let shared = PIAConnectionLiveActivityManager() + + private init() {} + + deinit { + endLiveActivities() + } + + public func startLiveActivity(with state: PIAConnectionAttributes.ContentState) { + guard activity == nil else { + updateLiveActivity(with: state) + return + } + + createNewLiveActivity(with: state) + + } + + public func endLiveActivities() { + let currentActivities = Activity.activities + + guard !currentActivities.isEmpty else { return } + + let semaphore = DispatchSemaphore(value: 0) + + Task { + for act in currentActivities { + await act.end(dismissalPolicy: .immediate) + + semaphore.signal() + } + } + semaphore.wait() + + } + + public func endPreviousActivities() { + let currentActivities = Activity.activities + for act in currentActivities { + Task { + await act.end(dismissalPolicy: .immediate) + } + } + activity = nil + } + + private func createNewLiveActivity(with state: PIAConnectionAttributes.ContentState) { + // Clear all the Live Activities before starting a new one + endPreviousActivities() + + let attributes = PIAConnectionAttributes() + + activity = try? Activity.request(attributes: attributes, contentState: state, pushType: nil) + } + + private func updateLiveActivity(with state: PIAConnectionAttributes.ContentState) { + guard activity?.activityState == .active else { + createNewLiveActivity(with: state) + return + } + // Only update the live activity if there is new content + guard state != activity?.content.state else { return } + + Task { + await activity?.update(using: state) + } + + } + +} diff --git a/PIAWidget/Domain/Widget/PIAWidget.swift b/PIAWidget/Domain/Widget/PIAWidget.swift new file mode 100644 index 000000000..b92986256 --- /dev/null +++ b/PIAWidget/Domain/Widget/PIAWidget.swift @@ -0,0 +1,49 @@ +// +// PIAWidget.swift +// PIA VPN +// +// Created by Jose Blaya on 24/09/2020. +// Copyright © 2020 Private Internet Access, Inc. +// +// This file is part of the Private Internet Access iOS Client. +// +// 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. + +// + +import WidgetKit +import SwiftUI +import Intents +import ActivityKit + +//@main +struct PIAWidget: Widget { + + let kind: String = "PIAWidget" + let displayName: String = "PIA VPN" + + var body: some WidgetConfiguration { + let widgetPersistenceDatasource = WidgetUserDefaultsDatasource() + return StaticConfiguration( + kind: kind, + provider: PIAWidgetProvider( + widgetPersistenceDatasource: widgetPersistenceDatasource + ) + ) { entry in + PIAWidgetView( + entry: entry, + widgetPersistenceDatasource: widgetPersistenceDatasource + ) + } + .configurationDisplayName(displayName) + .supportedFamilies([.systemSmall, .systemMedium]) + } +} diff --git a/PIAWidget/Domain/Widget/PIAWidgetAttributes.swift b/PIAWidget/Domain/Widget/PIAWidgetAttributes.swift new file mode 100644 index 000000000..cca8d72ab --- /dev/null +++ b/PIAWidget/Domain/Widget/PIAWidgetAttributes.swift @@ -0,0 +1,17 @@ + +import Foundation +import ActivityKit + +public struct PIAConnectionAttributes: ActivityAttributes { + public typealias PIAConnectionStatus = ContentState + + public struct ContentState: Codable, Hashable { + var connected: Bool + var regionName: String + var regionFlag: String + var vpnProtocol: String + + } + +} + diff --git a/PIAWidget/Domain/Widget/PIAWidgetBundle.swift b/PIAWidget/Domain/Widget/PIAWidgetBundle.swift new file mode 100644 index 000000000..4c2613b53 --- /dev/null +++ b/PIAWidget/Domain/Widget/PIAWidgetBundle.swift @@ -0,0 +1,14 @@ +import WidgetKit +import SwiftUI + +@main +struct PIAWidgetBundle: WidgetBundle { + var body: some Widget { + PIAWidget() + + if #available(iOS 16.1, *) { + PIAConnectionActivityWidget() + } + } +} + diff --git a/PIAWidget/Domain/Widget/PIAWidgetPreview.swift b/PIAWidget/Domain/Widget/PIAWidgetPreview.swift new file mode 100644 index 000000000..3bfd659c6 --- /dev/null +++ b/PIAWidget/Domain/Widget/PIAWidgetPreview.swift @@ -0,0 +1,38 @@ +// +// PIAWidgetPreview.swift +// PIAWidgetExtension +// +// Created by Juan Docal on 2022-09-28. +// Copyright © 2022 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import SwiftUI +import WidgetKit + +struct PIAWidgetPreview: PreviewProvider { + + static var previews: some View { + let widgetPersistenceDatasource = WidgetUserDefaultsDatasource() + PIAWidgetView( + entry: WidgetInformation( + date: Date(), + connected: true, + vpnProtocol: "IKEv2", + vpnPort: "500", + vpnSocket: "UDP" + ), + widgetPersistenceDatasource: widgetPersistenceDatasource + ).previewContext(WidgetPreviewContext(family: .systemSmall)) + PIAWidgetView( + entry: WidgetInformation( + date: Date(), + connected: false, + vpnProtocol: "WireGuard", + vpnPort: "1443", + vpnSocket: "UDP" + ), + widgetPersistenceDatasource: widgetPersistenceDatasource + ).previewContext(WidgetPreviewContext(family: .systemMedium)) + } +} diff --git a/PIAWidget/Domain/Widget/PIAWidgetProvider.swift b/PIAWidget/Domain/Widget/PIAWidgetProvider.swift new file mode 100644 index 000000000..269b10bd2 --- /dev/null +++ b/PIAWidget/Domain/Widget/PIAWidgetProvider.swift @@ -0,0 +1,73 @@ +// +// PIAWidgetProvider.swift +// PIAWidgetExtension +// +// Created by Juan Docal on 2022-09-28. +// Copyright © 2022 Private Internet Access Inc. All rights reserved. +// + +import Foundation +import WidgetKit + +struct PIAWidgetProvider: TimelineProvider { + + let widgetPersistenceDatasource: WidgetPersistenceDatasource + + init(widgetPersistenceDatasource: WidgetPersistenceDatasource) { + self.widgetPersistenceDatasource = widgetPersistenceDatasource + } + + func placeholder(in context: Context) -> WidgetInformation { + WidgetInformation( + date: Date(), + connected: false, + vpnProtocol: "IPSec (IKEv2)", + vpnPort: "500", + vpnSocket: "UDP" + ) + } + + func getSnapshot( + in context: Context, + completion: @escaping (WidgetInformation) -> () + ) { + let entry: WidgetInformation + entry = WidgetInformation( + date: Date(), + connected: widgetPersistenceDatasource.getIsVPNConnected(), + vpnProtocol: widgetPersistenceDatasource.getVpnProtocol(), + vpnPort: widgetPersistenceDatasource.getVpnPort(), + vpnSocket: widgetPersistenceDatasource.getVpnSocket() + ) + completion(entry) + } + + func getTimeline( + in context: Context, + completion: @escaping (Timeline) -> () + ) { + var entries: [WidgetInformation] = [] + + // Generate a timeline consisting of five entries an hour apart, + // starting from the current date. + let currentDate = Date() + for hourOffset in 0 ..< 5 { + let entryDate = Calendar.current.date( + byAdding: .hour, + value: hourOffset, + to: currentDate + )! + let entry = WidgetInformation( + date: entryDate, + connected: widgetPersistenceDatasource.getIsVPNConnected(), + vpnProtocol: widgetPersistenceDatasource.getVpnProtocol(), + vpnPort: widgetPersistenceDatasource.getVpnPort(), + vpnSocket: widgetPersistenceDatasource.getVpnSocket() + ) + entries.append(entry) + } + + let timeline = Timeline(entries: entries, policy: .atEnd) + completion(timeline) + } +} diff --git a/PIAWidget/PIAWidget.swift b/PIAWidget/PIAWidget.swift deleted file mode 100644 index 9338a85f2..000000000 --- a/PIAWidget/PIAWidget.swift +++ /dev/null @@ -1,166 +0,0 @@ -// -// PIAWidget.swift -// PIA VPN -// -// Created by Jose Blaya on 24/09/2020. -// Copyright © 2020 Private Internet Access, Inc. -// -// This file is part of the Private Internet Access iOS Client. -// -// 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. - -// - -import WidgetKit -import SwiftUI -import Intents - -struct Provider: TimelineProvider { - - func placeholder(in context: Context) -> WidgetContent { - WidgetContent(date: Date(), - connected: false, - vpnProtocol: "IPSec (IKEv2)", - vpnPort: "500", - vpnSocket: "UDP") - } - - func getSnapshot(in context: Context, completion: @escaping (WidgetContent) -> ()) { - let entry: WidgetContent - entry = WidgetContent(date: Date(), - connected: WidgetUtils.isVPNConnected, - vpnProtocol: WidgetUtils.vpnProtocol, - vpnPort: WidgetUtils.vpnPort, - vpnSocket: WidgetUtils.vpnSocket) - completion(entry) - } - - func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) { - var entries: [WidgetContent] = [] - - // Generate a timeline consisting of five entries an hour apart, starting from the current date. - let currentDate = Date() - for hourOffset in 0 ..< 5 { - let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)! - let entry = WidgetContent(date: entryDate, - connected: WidgetUtils.isVPNConnected, - vpnProtocol: WidgetUtils.vpnProtocol, - vpnPort: WidgetUtils.vpnPort, - vpnSocket: WidgetUtils.vpnSocket) - entries.append(entry) - } - - let timeline = Timeline(entries: entries, policy: .atEnd) - completion(timeline) - } -} - -struct PIAWidgetEntryView : View { - - @Environment(\.widgetFamily) var widgetFamily - - var entry: Provider.Entry - - var body: some View { - - ZStack(alignment: .bottomTrailing) { - - Image("robot") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: widgetFamily == .systemMedium ? 100 : 50, height: widgetFamily == .systemMedium ? 100 : 50, alignment: .center) - .rotationEffect(Angle(degrees: -35.0)) - .padding(widgetFamily == .systemMedium ? -25 : -9) - - HStack { - - if WidgetUtils.isTrustedNetwork { - - Circle() - .strokeBorder(Color("BorderColor"),lineWidth: 6) - .background(Circle() - .strokeBorder(Color("TrustedNetworkColor"),lineWidth: 8) - .background(Image("vpn-button") - .resizable() - .renderingMode(.template).foregroundColor(Color("TrustedNetworkColor")) - .aspectRatio(contentMode: .fit) - .frame(width: 40, height: 40, alignment: .center) - .padding(0))) - .padding(20) - - } else { - Circle() - .strokeBorder(Color("BorderColor"),lineWidth: 6) - .background(Circle() - .strokeBorder(Color(WidgetUtils.isVPNConnected ? "AccentColor" : "RedColor"),lineWidth: 8) - .background(Image("vpn-button") - .resizable() - .renderingMode(.template).foregroundColor(Color(WidgetUtils.isVPNConnected ? "AccentColor" : "RedColor")) - .aspectRatio(contentMode: .fit) - .frame(width: 40, height: 40, alignment: .center) - .padding(0))) - .padding(20) - - } - - if widgetFamily == .systemMedium { - VStack { - HStack(alignment: .center, spacing: 0) { - Image("icon-protocol").resizable().frame(width: 25, height: 25, alignment: .leading) - Spacer() - Text(WidgetUtils.vpnProtocol).font(.system(size: 14)).foregroundColor(Color("FontColor")).frame(maxWidth: .infinity, alignment: .leading) - } - HStack(alignment: .center, spacing: 0) { - Image("icon-port").resizable().frame(width: 25, height: 25, alignment: .leading) - Spacer() - Text(WidgetUtils.vpnPort).font(.system(size: 14)).foregroundColor(Color("FontColor")).frame(maxWidth: .infinity, alignment: .leading) - } - HStack(alignment: .center, spacing: 0) { - Image("icon-socket").resizable().frame(width: 25, height: 25, alignment: .leading) - Spacer() - Text(WidgetUtils.vpnSocket).font(.system(size: 14)).foregroundColor(Color("FontColor")).frame(maxWidth: .infinity, alignment: .leading) - } - }.padding(.trailing, 40) - - } - - } - - }.widgetURL(URL(string: widgetFamily == .systemMedium ? "piavpn:view" : "piavpn:connect")) - .background(Color("WidgetBackground")) - - } - -} - -@main -struct PIAWidget: Widget { - let kind: String = "PIAWidget" - - var body: some WidgetConfiguration { - StaticConfiguration(kind: kind, provider: Provider()) { entry in - PIAWidgetEntryView(entry: entry) - } - .configurationDisplayName("PIA VPN") - .description("") - .supportedFamilies([.systemSmall, .systemMedium]) - - } -} - -struct PIAWidget_Previews: PreviewProvider { - static var previews: some View { - PIAWidgetEntryView(entry: WidgetContent(date: Date(), connected: true, vpnProtocol: "IKEv2", vpnPort: "500", vpnSocket: "UDP")) - .previewContext(WidgetPreviewContext(family: .systemSmall)) - PIAWidgetEntryView(entry: WidgetContent(date: Date(), connected: false, vpnProtocol: "WireGuard", vpnPort: "1443", vpnSocket: "UDP")) - .previewContext(WidgetPreviewContext(family: .systemMedium)) - } -} diff --git a/Podfile b/Podfile index 3b145c576..383902b31 100644 --- a/Podfile +++ b/Podfile @@ -73,15 +73,15 @@ def shared_main_pods #pod "PIAAccountModule", :git => "#{$git_root}/#{$accounts_repo}" pod "PIAAccountModule", :git => "#{$gitlab_kn_root}/#{$accounts_gitlab_repo}", :commit => '697fd4f' #pod "PIARegionsModule", :git => "#{$git_root}/#{$regions_repo}" - pod "PIARegionsModule", :git => "#{$gitlab_kn_root}/#{$regions_gitlab_repo}", :branch => 'release/1.3.1' + pod "PIARegionsModule", :git => "#{$gitlab_kn_root}/#{$regions_gitlab_repo}", :branch => 'release/1.3.2' #pod "PIACSIModule", :git => "#{$git_root}/#{$csi_repo}" - pod "PIACSIModule", :git => "#{$gitlab_kn_root}/#{$csi_gitlab_repo}", :commit => 'b62d1bab' - pod "PIAKPIModule", :git => "#{$gitlab_kn_root}/#{$kpi_gitlab_repo}", :commit => '31186b1d' + pod "PIACSIModule", :git => "#{$gitlab_kn_root}/#{$csi_gitlab_repo}", :branch => 'release/1.0.2' + pod "PIAKPIModule", :git => "#{$gitlab_kn_root}/#{$kpi_gitlab_repo}", :branch => 'release/1.1.0' #library_by_path('~/Repositories') #library_by_git('') #library_by_gitlab_branch('') - library_by_gitlab_by_git('6d34ee34') + library_by_gitlab_by_git('cffdca05') #library_by_version('~> 1.1.3') end @@ -139,6 +139,10 @@ target 'PIA VPNTests' do pod 'Fabric' end +target 'PIA VPN UITests' do + app_pods +end + post_install do |installer| installer.pods_project.targets.each do |target| if ['PopupDialog'].include? target.name diff --git a/Podfile.lock b/Podfile.lock index 4080a35a3..f2ba577f2 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -70,19 +70,19 @@ PODS: - PIAAccountModule/gradle (= 1.2.1) - PIAAccountModule/account (1.2.1) - PIAAccountModule/gradle (1.2.1) - - PIACSIModule (1.0.1): - - PIACSIModule/csi (= 1.0.1) - - PIACSIModule/gradle (= 1.0.1) - - PIACSIModule/csi (1.0.1) - - PIACSIModule/gradle (1.0.1) - - PIAKPIModule (1.0.1): - - PIAKPIModule/gradle (= 1.0.1) - - PIAKPIModule/kpi (= 1.0.1) - - PIAKPIModule/gradle (1.0.1) - - PIAKPIModule/kpi (1.0.1) - - PIALibrary/Core (2.14.0): + - PIACSIModule (1.0.2): + - PIACSIModule/csi (= 1.0.2) + - PIACSIModule/gradle (= 1.0.2) + - PIACSIModule/csi (1.0.2) + - PIACSIModule/gradle (1.0.2) + - PIAKPIModule (1.1.0): + - PIAKPIModule/gradle (= 1.1.0) + - PIAKPIModule/kpi (= 1.1.0) + - PIAKPIModule/gradle (1.1.0) + - PIAKPIModule/kpi (1.1.0) + - PIALibrary/Core (2.18.0): - PIAAccountModule - - PIALibrary/Library (2.14.0): + - PIALibrary/Library (2.18.0): - Alamofire (~> 4) - Gloss (~> 2) - PIAAccountModule @@ -94,26 +94,26 @@ PODS: - PopupDialog - ReachabilitySwift - SwiftyBeaver - - PIALibrary/Mock (2.14.0): + - PIALibrary/Mock (2.18.0): - PIALibrary/Library - - PIALibrary/UI (2.14.0): + - PIALibrary/UI (2.18.0): - FXPageControl - lottie-ios - PIALibrary/Library - SwiftEntryKit (= 0.7.2) - SwiftyBeaver - TPKeyboardAvoiding - - PIALibrary/Util (2.14.0): + - PIALibrary/Util (2.18.0): - PIALibrary/Core - - PIALibrary/VPN (2.14.0): + - PIALibrary/VPN (2.18.0): - PIALibrary/Library - PIAWireguard - TunnelKit - - PIARegionsModule (1.3.1): - - PIARegionsModule/gradle (= 1.3.1) - - PIARegionsModule/regions (= 1.3.1) - - PIARegionsModule/gradle (1.3.1) - - PIARegionsModule/regions (1.3.1) + - PIARegionsModule (1.3.2): + - PIARegionsModule/gradle (= 1.3.2) + - PIARegionsModule/regions (= 1.3.2) + - PIARegionsModule/gradle (1.3.2) + - PIARegionsModule/regions (1.3.2) - PIAWireguard (1.2.0): - PIAWireguard/AppExtension (= 1.2.0) - PIAWireguard/Core (= 1.2.0) @@ -158,13 +158,13 @@ DEPENDENCIES: - GradientProgressBar (~> 2.0) - OpenSSL-Apple (from `https://github.com/keeshux/openssl-apple`) - "PIAAccountModule (from `git@gitlab.kape.com:pia-mobile/shared/account.git`, commit `697fd4f`)" - - "PIACSIModule (from `git@gitlab.kape.com:pia-mobile/shared/csi.git`, commit `b62d1bab`)" - - "PIAKPIModule (from `git@gitlab.kape.com:pia-mobile/shared/kpi.git`, commit `31186b1d`)" - - "PIALibrary/Library (from `git@gitlab.kape.com:pia-mobile/ios/client-library-apple.git`, commit `6d34ee34`)" - - "PIALibrary/Mock (from `git@gitlab.kape.com:pia-mobile/ios/client-library-apple.git`, commit `6d34ee34`)" - - "PIALibrary/UI (from `git@gitlab.kape.com:pia-mobile/ios/client-library-apple.git`, commit `6d34ee34`)" - - "PIALibrary/VPN (from `git@gitlab.kape.com:pia-mobile/ios/client-library-apple.git`, commit `6d34ee34`)" - - "PIARegionsModule (from `git@gitlab.kape.com:pia-mobile/shared/regions.git`, branch `release/1.3.1`)" + - "PIACSIModule (from `git@gitlab.kape.com:pia-mobile/shared/csi.git`, branch `release/1.0.2`)" + - "PIAKPIModule (from `git@gitlab.kape.com:pia-mobile/shared/kpi.git`, branch `release/1.1.0`)" + - "PIALibrary/Library (from `git@gitlab.kape.com:pia-mobile/ios/client-library-apple.git`, commit `cffdca05`)" + - "PIALibrary/Mock (from `git@gitlab.kape.com:pia-mobile/ios/client-library-apple.git`, commit `cffdca05`)" + - "PIALibrary/UI (from `git@gitlab.kape.com:pia-mobile/ios/client-library-apple.git`, commit `cffdca05`)" + - "PIALibrary/VPN (from `git@gitlab.kape.com:pia-mobile/ios/client-library-apple.git`, commit `cffdca05`)" + - "PIARegionsModule (from `git@gitlab.kape.com:pia-mobile/shared/regions.git`, branch `release/1.3.2`)" - "PIAWireguard (from `git@gitlab.kape.com:pia-mobile/ios/pia-wireguard.git`, commit `7e9d8d48`)" - Popover - PopupDialog @@ -211,16 +211,16 @@ EXTERNAL SOURCES: :commit: 697fd4f :git: "git@gitlab.kape.com:pia-mobile/shared/account.git" PIACSIModule: - :commit: b62d1bab + :branch: release/1.0.2 :git: "git@gitlab.kape.com:pia-mobile/shared/csi.git" PIAKPIModule: - :commit: 31186b1d + :branch: release/1.1.0 :git: "git@gitlab.kape.com:pia-mobile/shared/kpi.git" PIALibrary: - :commit: 6d34ee34 + :commit: cffdca05 :git: "git@gitlab.kape.com:pia-mobile/ios/client-library-apple.git" PIARegionsModule: - :branch: release/1.3.1 + :branch: release/1.3.2 :git: "git@gitlab.kape.com:pia-mobile/shared/regions.git" PIAWireguard: :commit: 7e9d8d48 @@ -237,16 +237,16 @@ CHECKOUT OPTIONS: :commit: 697fd4f :git: "git@gitlab.kape.com:pia-mobile/shared/account.git" PIACSIModule: - :commit: b62d1bab + :commit: 73b766fbb07c351016287f674f857b01d575ecd7 :git: "git@gitlab.kape.com:pia-mobile/shared/csi.git" PIAKPIModule: - :commit: 31186b1d + :commit: e444c78b61e280a1ce444d8d8a3a4c0eeb50b981 :git: "git@gitlab.kape.com:pia-mobile/shared/kpi.git" PIALibrary: - :commit: 6d34ee34 + :commit: cffdca05 :git: "git@gitlab.kape.com:pia-mobile/ios/client-library-apple.git" PIARegionsModule: - :commit: 6b3b763b3b1d066cb73d2d8833563669ff8e87bb + :commit: 355418cf4b3d35512c345e51026fbabf81fe6488 :git: "git@gitlab.kape.com:pia-mobile/shared/regions.git" PIAWireguard: :commit: 7e9d8d48 @@ -276,10 +276,10 @@ SPEC CHECKSUMS: nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd OpenSSL-Apple: bb7c9715a259404de040f5359ed3b3170cedf8d6 PIAAccountModule: 31264ad54dfa98cd8be6810885f910b8bedc9592 - PIACSIModule: 32df98c20a0fc4cad5fadbb1b72f7b74315aa8ea - PIAKPIModule: ec04bedfc7e6eccc7dfe4bc630a99c104ffbb7ea - PIALibrary: d52e06ca2995dd5692dcadb678475acbb0000cd2 - PIARegionsModule: eff00bd28dea554d7b766ec5d7e9a74ab448f5fe + PIACSIModule: 8ee47a1037bb7f3fbe61a0d70df29ca538e77edb + PIAKPIModule: 37c56c0153d693db4d4adb43fd12b9c96ec7ad6d + PIALibrary: ed53091a5bc74f77354481729eff87f6c07fd00d + PIARegionsModule: f54391cbb218b2780612158c54bd8deeda6941d9 PIAWireguard: e6fc3a37758af8d83704dd61e327c2ff6da88b13 Popover: 10e1d9528f81d9504df984b7b3f491292bc1822d PopupDialog: 720c92befd8bc23c13442254945213db5612f149 @@ -293,6 +293,6 @@ SPEC CHECKSUMS: TunnelKit: 2a6aadea2d772a2760b153aee27d1c334c9ca6db TweetNacl: 3abf4d1d2082b0114e7a67410e300892448951e6 -PODFILE CHECKSUM: 5b7ee3e88860d684f51498a697fb96c685f63397 +PODFILE CHECKSUM: 5da459779bbfdfae20771eca5db526da51714419 COCOAPODS: 1.11.2 diff --git a/README.md b/README.md index a870fa1bc..feea50969 100644 --- a/README.md +++ b/README.md @@ -31,33 +31,11 @@ The PIA VPN app features: - Xcode 9+ (Swift 4) - Git (preinstalled with Xcode Command Line Tools) - Ruby (preinstalled with macOS) -- [CocoaPods 1.5.0][dep-cocoapods] - [SwiftGen][dep-swiftgen] - [Go][dep-golang] It's highly recommended to use the Git and Ruby packages provided by [Homebrew][dep-brew]. -### Testing - -Download the app codebase locally: - - $ git clone https://github.com/pia-foss/vpn-ios.git - -Assuming you have a [working CocoaPods environment][dep-cocoapods], setting up the app workspace only requires installing the pod dependencies: - - $ pod install - -After that, open `PIA VPN.xcworkspace` in Xcode and run the `PIA VPN` target. - -If the build does not complete due to missing modules (often `PIAAccount`), run `pod install` again with the partial build, then build again. - -For the VPN to work properly, the app requires: - -- _App Groups_ and _Keychain Sharing_ capabilities -- App IDs with _Packet Tunnel_ entitlements - -both in the main app and the tunnel extension target. - ### Hotspot Helper API We use a special entitlement to participate in the process of joining Wi-Fi/hotspot networks (https://developer.apple.com/documentation/networkextension/nehotspothelper) @@ -101,7 +79,6 @@ This project is licensed under the [MIT (Expat) license](https://choosealicense. [pia-url]: https://www.privateinternetaccess.com/ [pia-wiki]: https://en.wikipedia.org/wiki/Private_Internet_Access -[dep-cocoapods]: https://guides.cocoapods.org/using/getting-started.html [dep-swiftgen]: https://github.com/SwiftGen/SwiftGen [dep-jazzy]: https://github.com/realm/jazzy [dep-brew]: https://brew.sh/ diff --git a/Resources/GoogleService-Info.plist b/Resources/GoogleService-Info.plist deleted file mode 100644 index 0c67376eb..000000000 --- a/Resources/GoogleService-Info.plist +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/Resources/Resources/Shared/ar.lproj/UI.strings b/Resources/Resources/Shared/ar.lproj/UI.strings new file mode 100644 index 000000000..d93d9b375 --- /dev/null +++ b/Resources/Resources/Shared/ar.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "الإصدار %@ (%@)"; +"global.close" = "إغلاق"; +"global.ok" = "موافق"; +"global.cancel" = "إلغاء"; diff --git a/Resources/Resources/Shared/da.lproj/UI.strings b/Resources/Resources/Shared/da.lproj/UI.strings new file mode 100644 index 000000000..ef42d7faf --- /dev/null +++ b/Resources/Resources/Shared/da.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Luk"; +"global.ok" = "OK"; +"global.cancel" = "Annuller"; diff --git a/Resources/Resources/Shared/de.lproj/UI.strings b/Resources/Resources/Shared/de.lproj/UI.strings new file mode 100644 index 000000000..4268a80ca --- /dev/null +++ b/Resources/Resources/Shared/de.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Schließen"; +"global.ok" = "OK"; +"global.cancel" = "Abbrechen"; diff --git a/Resources/Resources/Shared/en.lproj/UI.strings b/Resources/Resources/Shared/en.lproj/UI.strings new file mode 100644 index 000000000..98ec3d5e2 --- /dev/null +++ b/Resources/Resources/Shared/en.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Close"; +"global.ok" = "OK"; +"global.cancel" = "Cancel"; diff --git a/Resources/Resources/Shared/es-MX.lproj/UI.strings b/Resources/Resources/Shared/es-MX.lproj/UI.strings new file mode 100644 index 000000000..e645f72b5 --- /dev/null +++ b/Resources/Resources/Shared/es-MX.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versión %@ (%@)"; +"global.close" = "Cerrar"; +"global.ok" = "Aceptar"; +"global.cancel" = "Cancelar"; diff --git a/Resources/Resources/Shared/fr.lproj/UI.strings b/Resources/Resources/Shared/fr.lproj/UI.strings new file mode 100644 index 000000000..fffdf519f --- /dev/null +++ b/Resources/Resources/Shared/fr.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Version %@ (%@)"; +"global.close" = "Fermer"; +"global.ok" = "OK"; +"global.cancel" = "Annuler"; diff --git a/Resources/Resources/Shared/it.lproj/UI.strings b/Resources/Resources/Shared/it.lproj/UI.strings new file mode 100644 index 000000000..fc2c6c196 --- /dev/null +++ b/Resources/Resources/Shared/it.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versione %@ (%@)"; +"global.close" = "Chiudi"; +"global.ok" = "OK"; +"global.cancel" = "Annulla"; diff --git a/Resources/Resources/Shared/ja.lproj/UI.strings b/Resources/Resources/Shared/ja.lproj/UI.strings new file mode 100644 index 000000000..1751458e6 --- /dev/null +++ b/Resources/Resources/Shared/ja.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "バージョン%@ (%@)"; +"global.close" = "閉じる"; +"global.ok" = "OK"; +"global.cancel" = "キャンセル"; diff --git a/Resources/Resources/Shared/ko.lproj/UI.strings b/Resources/Resources/Shared/ko.lproj/UI.strings new file mode 100644 index 000000000..1c9f1e509 --- /dev/null +++ b/Resources/Resources/Shared/ko.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "버전 %@ (%@)"; +"global.close" = "닫기"; +"global.ok" = "확인"; +"global.cancel" = "취소"; diff --git a/Resources/Resources/Shared/nb.lproj/UI.strings b/Resources/Resources/Shared/nb.lproj/UI.strings new file mode 100644 index 000000000..5ccb0d7dc --- /dev/null +++ b/Resources/Resources/Shared/nb.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versjon %@ (%@)"; +"global.close" = "Lukk"; +"global.ok" = "OK"; +"global.cancel" = "Avbryt"; diff --git a/Resources/Resources/Shared/nl.lproj/UI.strings b/Resources/Resources/Shared/nl.lproj/UI.strings new file mode 100644 index 000000000..0131eaac3 --- /dev/null +++ b/Resources/Resources/Shared/nl.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versie %@ (%@)"; +"global.close" = "Sluiten"; +"global.ok" = "OK"; +"global.cancel" = "Annuleren"; diff --git a/Resources/Resources/Shared/pl.lproj/UI.strings b/Resources/Resources/Shared/pl.lproj/UI.strings new file mode 100644 index 000000000..fccbc42bf --- /dev/null +++ b/Resources/Resources/Shared/pl.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Wersja %@ (%@)"; +"global.close" = "Zamknij"; +"global.ok" = "OK"; +"global.cancel" = "Anuluj"; diff --git a/Resources/Resources/Shared/pt-BR.lproj/UI.strings b/Resources/Resources/Shared/pt-BR.lproj/UI.strings new file mode 100644 index 000000000..32e6d7e28 --- /dev/null +++ b/Resources/Resources/Shared/pt-BR.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Versão %@ (%@)"; +"global.close" = "Fechar"; +"global.ok" = "OK"; +"global.cancel" = "Cancelar"; diff --git a/Resources/Resources/Shared/ru.lproj/UI.strings b/Resources/Resources/Shared/ru.lproj/UI.strings new file mode 100644 index 000000000..2d1416365 --- /dev/null +++ b/Resources/Resources/Shared/ru.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "Версия %@ (%@)"; +"global.close" = "Закрыть"; +"global.ok" = "ОК"; +"global.cancel" = "Отмена"; diff --git a/Resources/Resources/Shared/th.lproj/UI.strings b/Resources/Resources/Shared/th.lproj/UI.strings new file mode 100644 index 000000000..3069ecff4 --- /dev/null +++ b/Resources/Resources/Shared/th.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "เวอร์ชั่น %@ (%@)"; +"global.close" = "ปิด"; +"global.ok" = "ตกลง"; +"global.cancel" = "ยกเลิก"; diff --git a/Resources/Resources/Shared/tr.lproj/UI.strings b/Resources/Resources/Shared/tr.lproj/UI.strings new file mode 100644 index 000000000..fc6795eb9 --- /dev/null +++ b/Resources/Resources/Shared/tr.lproj/UI.strings @@ -0,0 +1,12 @@ +/* (No Comment) */ +"global.cancel" = "İptal"; + +/* (No Comment) */ +"global.close" = "Kapat"; + +/* (No Comment) */ +"global.ok" = "Tamam"; + +/* (No Comment) */ +"global.version.format" = "Sürüm %@ (%@)"; + diff --git a/Resources/Resources/Shared/zh-Hans.lproj/UI.strings b/Resources/Resources/Shared/zh-Hans.lproj/UI.strings new file mode 100644 index 000000000..e6f012399 --- /dev/null +++ b/Resources/Resources/Shared/zh-Hans.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "版本 %@ (%@)"; +"global.close" = "关闭"; +"global.ok" = "确定"; +"global.cancel" = "取消"; diff --git a/Resources/Resources/Shared/zh-Hant.lproj/UI.strings b/Resources/Resources/Shared/zh-Hant.lproj/UI.strings new file mode 100644 index 000000000..7d68e2272 --- /dev/null +++ b/Resources/Resources/Shared/zh-Hant.lproj/UI.strings @@ -0,0 +1,4 @@ +"global.version.format" = "版本 %@ (%@)"; +"global.close" = "關閉"; +"global.ok" = "確認"; +"global.cancel" = "取消"; diff --git a/Resources/Resources/iOS/UI.xcassets/Contents.json b/Resources/Resources/iOS/UI.xcassets/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Contents.json new file mode 100644 index 000000000..da4a164c9 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/centered-dark-map.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/centered-dark-map.imageset/Contents.json new file mode 100644 index 000000000..cb11bdd29 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/centered-dark-map.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "darkDotsCopy2.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/centered-dark-map.imageset/darkDotsCopy2.pdf b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/centered-dark-map.imageset/darkDotsCopy2.pdf new file mode 100644 index 000000000..fa02be2ae Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/centered-dark-map.imageset/darkDotsCopy2.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/centered-light-map.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/centered-light-map.imageset/Contents.json new file mode 100644 index 000000000..2e6412708 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/centered-light-map.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "group.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/centered-light-map.imageset/group.pdf b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/centered-light-map.imageset/group.pdf new file mode 100644 index 000000000..225c9533b Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/centered-light-map.imageset/group.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/computer-icon.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/computer-icon.imageset/Contents.json new file mode 100644 index 000000000..3be8cd667 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/computer-icon.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "computer-7.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "computer-7@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "computer-7@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/computer-icon.imageset/computer-7.png b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/computer-icon.imageset/computer-7.png new file mode 100644 index 000000000..c655b4382 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/computer-icon.imageset/computer-7.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/computer-icon.imageset/computer-7@2x.png b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/computer-icon.imageset/computer-7@2x.png new file mode 100644 index 000000000..832367a12 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/computer-icon.imageset/computer-7@2x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/computer-icon.imageset/computer-7@3x.png b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/computer-icon.imageset/computer-7@3x.png new file mode 100644 index 000000000..56aac76eb Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/computer-icon.imageset/computer-7@3x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/globe-icon.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/globe-icon.imageset/Contents.json new file mode 100644 index 000000000..f65cff056 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/globe-icon.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "globe-turn-7.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "globe-turn-7@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "globe-turn-7@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/globe-icon.imageset/globe-turn-7.png b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/globe-icon.imageset/globe-turn-7.png new file mode 100644 index 000000000..7b578a284 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/globe-icon.imageset/globe-turn-7.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/globe-icon.imageset/globe-turn-7@2x.png b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/globe-icon.imageset/globe-turn-7@2x.png new file mode 100644 index 000000000..9c178500c Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/globe-icon.imageset/globe-turn-7@2x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/globe-icon.imageset/globe-turn-7@3x.png b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/globe-icon.imageset/globe-turn-7@3x.png new file mode 100644 index 000000000..35ff13f83 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/globe-icon.imageset/globe-turn-7@3x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-back.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-back.imageset/Contents.json new file mode 100644 index 000000000..6679f0b09 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-back.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "backIconCopy-2.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-back.imageset/backIconCopy-2.pdf b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-back.imageset/backIconCopy-2.pdf new file mode 100644 index 000000000..b70bce618 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-back.imageset/backIconCopy-2.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-camera.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-camera.imageset/Contents.json new file mode 100644 index 000000000..bce0a6471 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-camera.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "scanIcon.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-camera.imageset/scanIcon.pdf b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-camera.imageset/scanIcon.pdf new file mode 100644 index 000000000..8745d7a04 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-camera.imageset/scanIcon.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-close.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-close.imageset/Contents.json new file mode 100644 index 000000000..a8f99392e --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-close.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "group104Copy.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-close.imageset/group104Copy.pdf b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-close.imageset/group104Copy.pdf new file mode 100644 index 000000000..2d3748c0f Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-close.imageset/group104Copy.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-warning.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-warning.imageset/Contents.json new file mode 100644 index 000000000..c8ddbf654 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-warning.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "warningIconCopy4.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-warning.imageset/warningIconCopy4.pdf b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-warning.imageset/warningIconCopy4.pdf new file mode 100644 index 000000000..0bf4d9890 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/icon-warning.imageset/warningIconCopy4.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/pagecontrol-selected-dot.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/pagecontrol-selected-dot.imageset/Contents.json new file mode 100644 index 000000000..c3b980050 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/pagecontrol-selected-dot.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "group4.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/pagecontrol-selected-dot.imageset/group4.pdf b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/pagecontrol-selected-dot.imageset/group4.pdf new file mode 100644 index 000000000..7664ef04f Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/pagecontrol-selected-dot.imageset/group4.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/pagecontrol-unselected-dot.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/pagecontrol-unselected-dot.imageset/Contents.json new file mode 100644 index 000000000..1ed8a5b8f --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/pagecontrol-unselected-dot.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "oval2Copy.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/pagecontrol-unselected-dot.imageset/oval2Copy.pdf b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/pagecontrol-unselected-dot.imageset/oval2Copy.pdf new file mode 100644 index 000000000..66e36df5f Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/pagecontrol-unselected-dot.imageset/oval2Copy.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/plan-selected.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/plan-selected.imageset/Contents.json new file mode 100644 index 000000000..fecd64dd0 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/plan-selected.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "group3.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/plan-selected.imageset/group3.pdf b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/plan-selected.imageset/group3.pdf new file mode 100644 index 000000000..7c72ff40f Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/plan-selected.imageset/group3.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/plan-unselected.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/plan-unselected.imageset/Contents.json new file mode 100644 index 000000000..7d4eb15e4 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/plan-unselected.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "oval3.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/plan-unselected.imageset/oval3.pdf b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/plan-unselected.imageset/oval3.pdf new file mode 100644 index 000000000..39296d491 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/plan-unselected.imageset/oval3.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/scrollableMap-dark.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/scrollableMap-dark.imageset/Contents.json new file mode 100644 index 000000000..24094a461 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/scrollableMap-dark.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "map-dark-walkthrough.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/scrollableMap-dark.imageset/map-dark-walkthrough.pdf b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/scrollableMap-dark.imageset/map-dark-walkthrough.pdf new file mode 100644 index 000000000..598eb2127 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/scrollableMap-dark.imageset/map-dark-walkthrough.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/scrollableMap-light.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/scrollableMap-light.imageset/Contents.json new file mode 100644 index 000000000..24d22d23a --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/scrollableMap-light.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "map-light-walkthrough.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/scrollableMap-light.imageset/map-light-walkthrough.pdf b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/scrollableMap-light.imageset/map-light-walkthrough.pdf new file mode 100644 index 000000000..9f7cd1cf2 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/scrollableMap-light.imageset/map-light-walkthrough.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/shield-icon.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/shield-icon.imageset/Contents.json new file mode 100644 index 000000000..ea0da821e --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/shield-icon.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "shield-7.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "shield-7@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "shield-7@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/shield-icon.imageset/shield-7.png b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/shield-icon.imageset/shield-7.png new file mode 100644 index 000000000..9d5a9b9b9 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/shield-icon.imageset/shield-7.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/shield-icon.imageset/shield-7@2x.png b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/shield-icon.imageset/shield-7@2x.png new file mode 100644 index 000000000..35489829c Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/shield-icon.imageset/shield-7@2x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/PIAX/Global/shield-icon.imageset/shield-7@3x.png b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/shield-icon.imageset/shield-7@3x.png new file mode 100644 index 000000000..fcfa17137 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/PIAX/Global/shield-icon.imageset/shield-7@3x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/close-icon.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/close-icon.imageset/Contents.json new file mode 100644 index 000000000..063263d21 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/close-icon.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "close_button@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "close_button@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/close-icon.imageset/close_button@2x.png b/Resources/Resources/iOS/UI.xcassets/close-icon.imageset/close_button@2x.png new file mode 100644 index 000000000..5b23b62c9 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/close-icon.imageset/close_button@2x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/close-icon.imageset/close_button@3x.png b/Resources/Resources/iOS/UI.xcassets/close-icon.imageset/close_button@3x.png new file mode 100644 index 000000000..160a6c060 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/close-icon.imageset/close_button@3x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-account-failed.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/image-account-failed.imageset/Contents.json new file mode 100644 index 000000000..36439e32c --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/image-account-failed.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "signup-error.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Resources/Resources/iOS/UI.xcassets/image-account-failed.imageset/signup-error.pdf b/Resources/Resources/iOS/UI.xcassets/image-account-failed.imageset/signup-error.pdf new file mode 100644 index 000000000..711c9d689 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/image-account-failed.imageset/signup-error.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-document-consent.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/image-document-consent.imageset/Contents.json new file mode 100644 index 000000000..53ef85ddc --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/image-document-consent.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "consent-icon.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Resources/Resources/iOS/UI.xcassets/image-document-consent.imageset/consent-icon.pdf b/Resources/Resources/iOS/UI.xcassets/image-document-consent.imageset/consent-icon.pdf new file mode 100644 index 000000000..b91347418 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/image-document-consent.imageset/consent-icon.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-no-internet.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/image-no-internet.imageset/Contents.json new file mode 100644 index 000000000..828c33b9a --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/image-no-internet.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "no-internet-dark.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Resources/Resources/iOS/UI.xcassets/image-no-internet.imageset/no-internet-dark.pdf b/Resources/Resources/iOS/UI.xcassets/image-no-internet.imageset/no-internet-dark.pdf new file mode 100644 index 000000000..c7d799ecc Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/image-no-internet.imageset/no-internet-dark.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-purchase-success.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/image-purchase-success.imageset/Contents.json new file mode 100644 index 000000000..713ce5e6b --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/image-purchase-success.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "image-purchase-success@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "image-purchase-success@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/image-purchase-success.imageset/image-purchase-success@2x.png b/Resources/Resources/iOS/UI.xcassets/image-purchase-success.imageset/image-purchase-success@2x.png new file mode 100644 index 000000000..61beeb699 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/image-purchase-success.imageset/image-purchase-success@2x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-purchase-success.imageset/image-purchase-success@3x.png b/Resources/Resources/iOS/UI.xcassets/image-purchase-success.imageset/image-purchase-success@3x.png new file mode 100644 index 000000000..a1dc10d72 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/image-purchase-success.imageset/image-purchase-success@3x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-receipt-background.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/image-receipt-background.imageset/Contents.json new file mode 100644 index 000000000..978980d7e --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/image-receipt-background.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "image-receipt-background@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "image-receipt-background@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/image-receipt-background.imageset/image-receipt-background@2x.png b/Resources/Resources/iOS/UI.xcassets/image-receipt-background.imageset/image-receipt-background@2x.png new file mode 100644 index 000000000..dc7214046 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/image-receipt-background.imageset/image-receipt-background@2x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-receipt-background.imageset/image-receipt-background@3x.png b/Resources/Resources/iOS/UI.xcassets/image-receipt-background.imageset/image-receipt-background@3x.png new file mode 100644 index 000000000..31969f7fb Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/image-receipt-background.imageset/image-receipt-background@3x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-redeem-claimed.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/image-redeem-claimed.imageset/Contents.json new file mode 100644 index 000000000..488339966 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/image-redeem-claimed.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "image-redeem-claimed@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "image-redeem-claimed@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/image-redeem-claimed.imageset/image-redeem-claimed@2x.png b/Resources/Resources/iOS/UI.xcassets/image-redeem-claimed.imageset/image-redeem-claimed@2x.png new file mode 100644 index 000000000..b5a3fa9ef Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/image-redeem-claimed.imageset/image-redeem-claimed@2x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-redeem-claimed.imageset/image-redeem-claimed@3x.png b/Resources/Resources/iOS/UI.xcassets/image-redeem-claimed.imageset/image-redeem-claimed@3x.png new file mode 100644 index 000000000..8f47cf215 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/image-redeem-claimed.imageset/image-redeem-claimed@3x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-redeem-invalid.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/image-redeem-invalid.imageset/Contents.json new file mode 100644 index 000000000..d85f8073a --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/image-redeem-invalid.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "gift-card-error.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Resources/Resources/iOS/UI.xcassets/image-redeem-invalid.imageset/gift-card-error.pdf b/Resources/Resources/iOS/UI.xcassets/image-redeem-invalid.imageset/gift-card-error.pdf new file mode 100644 index 000000000..7109baad6 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/image-redeem-invalid.imageset/gift-card-error.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-redeem-success.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/image-redeem-success.imageset/Contents.json new file mode 100644 index 000000000..327612fa0 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/image-redeem-success.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "sign-up-email.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Resources/Resources/iOS/UI.xcassets/image-redeem-success.imageset/sign-up-email.pdf b/Resources/Resources/iOS/UI.xcassets/image-redeem-success.imageset/sign-up-email.pdf new file mode 100644 index 000000000..0a76e648f Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/image-redeem-success.imageset/sign-up-email.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-walkthrough-1.imageset/01IllustrationWalkthroughScreen.pdf b/Resources/Resources/iOS/UI.xcassets/image-walkthrough-1.imageset/01IllustrationWalkthroughScreen.pdf new file mode 100644 index 000000000..73621d8e3 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/image-walkthrough-1.imageset/01IllustrationWalkthroughScreen.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-walkthrough-1.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/image-walkthrough-1.imageset/Contents.json new file mode 100644 index 000000000..09d6c52ff --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/image-walkthrough-1.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "01IllustrationWalkthroughScreen.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/image-walkthrough-2.imageset/02IllustrationWalkthroughGlobe.pdf b/Resources/Resources/iOS/UI.xcassets/image-walkthrough-2.imageset/02IllustrationWalkthroughGlobe.pdf new file mode 100644 index 000000000..4b3a393cb Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/image-walkthrough-2.imageset/02IllustrationWalkthroughGlobe.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-walkthrough-2.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/image-walkthrough-2.imageset/Contents.json new file mode 100644 index 000000000..3f5478ed4 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/image-walkthrough-2.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "02IllustrationWalkthroughGlobe.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/image-walkthrough-3.imageset/03IllustrationWalkthroughShield.pdf b/Resources/Resources/iOS/UI.xcassets/image-walkthrough-3.imageset/03IllustrationWalkthroughShield.pdf new file mode 100644 index 000000000..13136e585 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/image-walkthrough-3.imageset/03IllustrationWalkthroughShield.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/image-walkthrough-3.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/image-walkthrough-3.imageset/Contents.json new file mode 100644 index 000000000..5dc39a9d7 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/image-walkthrough-3.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "03IllustrationWalkthroughShield.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/nav-logo.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/nav-logo.imageset/Contents.json new file mode 100644 index 000000000..9dee98208 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/nav-logo.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "pia-logo-light-horizontal-128.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Resources/Resources/iOS/UI.xcassets/nav-logo.imageset/pia-logo-light-horizontal-128.pdf b/Resources/Resources/iOS/UI.xcassets/nav-logo.imageset/pia-logo-light-horizontal-128.pdf new file mode 100644 index 000000000..e6dd96640 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/nav-logo.imageset/pia-logo-light-horizontal-128.pdf differ diff --git a/Resources/Resources/iOS/UI.xcassets/qr-code.imageset/Contents.json b/Resources/Resources/iOS/UI.xcassets/qr-code.imageset/Contents.json new file mode 100644 index 000000000..5f2018ed7 --- /dev/null +++ b/Resources/Resources/iOS/UI.xcassets/qr-code.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "ic_qr_code@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_qr_code@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Resources/Resources/iOS/UI.xcassets/qr-code.imageset/ic_qr_code@2x.png b/Resources/Resources/iOS/UI.xcassets/qr-code.imageset/ic_qr_code@2x.png new file mode 100644 index 000000000..6e729dc91 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/qr-code.imageset/ic_qr_code@2x.png differ diff --git a/Resources/Resources/iOS/UI.xcassets/qr-code.imageset/ic_qr_code@3x.png b/Resources/Resources/iOS/UI.xcassets/qr-code.imageset/ic_qr_code@3x.png new file mode 100644 index 000000000..ec768c4d2 Binary files /dev/null and b/Resources/Resources/iOS/UI.xcassets/qr-code.imageset/ic_qr_code@3x.png differ diff --git a/Resources/Resources/iOS/ar.lproj/Signup.strings b/Resources/Resources/iOS/ar.lproj/Signup.strings new file mode 100644 index 000000000..ce7d9f39d --- /dev/null +++ b/Resources/Resources/iOS/ar.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "تأكيد التسجيل"; +"in_progress.message" = "جارٍ تأكيد عملية الشراء مع نظامنا. يمكن أن يستغرق ذلك لحظة لذلك انتظر قليلًا."; +"in_progress.redeem.message" = "جارٍ تأكيد رمز بطاقتك مع نظامنا. قد يستغرق ذلك بضع لحظات، انتظر قليلًا."; + +"success.title" = "تم الشراء"; +"success.message_format" = "شضكراً على اشتراكك معنا. لقد أرسلنا اسم المستخدم وكلمة المرور الخاصين بك إلى بريدك الإلكتروني %@"; +"success.redeem.title" = "تم استبدال البطاقة بنجاح"; +"success.redeem.message" = "ستصلك رسالة عبر البريد الإلكتروني تتضمن اسم المستخدم وكلمة المرور.\n\nتفاصيل تسجيل الدخول"; +"success.username.caption" = "اسم المستخدم"; +"success.password.caption" = "كلمة المرور"; +"success.submit" = "كيف تبدأ"; + +"failure.vc_title" = "فشل تسجيل الآن"; +"failure.title" = "فشل إنشاء الحساب"; +"failure.message" = "يتعذر علينا إنشاء حساب في الوقت الحالي. يرجى إعادة المحاولة لاحقًا. \n\nعند إعادة فتح التطبيق سيتم إعادة محاولة إنشاء حساب."; +"failure.purchase.sandbox.message" = "اشتراك الصندوق المحدد غير متاح في الإنتاج."; +"failure.redeem.invalid.title" = "رمز بطاقة غير صالح"; +"failure.redeem.invalid.message" = "يبدو أنك أدخلت رمز بطاقة غير صالح. يرجى إعادة المحاولة."; +"failure.redeem.claimed.title" = "تم استخدام هذه البطاقة بالفعل"; +"failure.redeem.claimed.message" = "يبدو أن هذه البطاقة استُخدمت في حساب آخر. حاول إدخال رمز جديد."; +"failure.submit" = "عودة"; + +"unreachable.vc_title" = "خطأ"; +"unreachable.title" = "أوبس!"; +"unreachable.message" = "لم يتم العثور على اتصال بالإنترنت. يرجى التأكد من اتصالك بالإنترنت وضغط زر إعادة المحاولة أدناه.\n\nيمكنك العودة إلى التطبيق في وقت لاحق لإنهاء العملية."; +"unreachable.submit" = "أعد المحاولة"; + +"purchase.uncredited.alert.message" = "لديك معاملات غير معتمدة. هل تريد استعادة تفاصيل حسابك؟"; +"purchase.uncredited.alert.button.cancel" = "إلغاء"; +"purchase.uncredited.alert.button.recover" = "استعادة الحساب"; + +"purchase.trials.intro" = "ابدأ تجربتك المجانية لمدة 7 ايام"; +"purchase.trials.price.after" = "ثم %@"; +"purchase.trials.money.back" = "ضمان استرداد المال لمدة 30 أيام"; +"purchase.trials.1year.protection" = "1 سنة من الخصوصية وحماية الهوية"; +"purchase.trials.anonymous" = "تصفح مجهول الهوية وإخفاء عنوان IP."; +"purchase.trials.devices" = "يدعم 10 أجهزة في المرة الواحدة"; +"purchase.trials.devices.description" = "احمي نفسك على ما يصل إلى 10 أجهزة في وقت واحد."; +"purchase.trials.region" = "اتصل بأي منطقة بسهولة"; +"purchase.trials.servers" = "أكثر من 3300 خادم في 32 دولة"; +"purchase.trials.start" = "ابدأ الاشتراك"; +"purchase.trials.all.plans" = "مشاهدة جميع الخطط المتاحة"; + +"purchase.subscribe.now" = "اشتراك الآن"; + +// WALKTHROUGH + +"walkthrough.action.next" = "التالي"; +"walkthrough.action.done" = "تم"; +"walkthrough.action.skip" = "تخطي"; + +"walkthrough.page.1.title" = "يدعم 10 أجهزة في المرة الواحدة"; +"walkthrough.page.1.description" = "احمي نفسك على ما يصل إلى 10 أجهزة في وقت واحد."; +"walkthrough.page.2.title" = "اتصل بأي منطقة بسهولة"; +"walkthrough.page.2.description" = "مع خوادم في جميع أنحاء العالم، أنت دائما تحت الحماية."; +"walkthrough.page.3.title" = "احمي نفسك من الإعلانات"; +"walkthrough.page.3.description" = "تمكين ميزة حظر المحتوى يمنع الإعلانات من الظهور في Safari."; + +"share.data.buttons.accept" = "قبول"; +"share.data.buttons.noThanks" = "لا، شكرًا"; +"share.data.buttons.readMore" = "قراءة المزيد"; +"share.data.text.title" = "يرجى مساعدتنا في تحسين خدمتنا"; +"share.data.text.description" = "لمساعدتنا في ضمان أداء اتصال خدمتنا، يمكنك مشاركة إحصائيات اتصالك معنا دون الكشف عن هويتك. لا تتضمن هذه التقارير أي معلومات محددة للشخصية."; +"share.data.text.footer" = "يمكنك دائمًا التحكم في ذلك من إعداداتك"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/ar.lproj/Welcome.strings b/Resources/Resources/iOS/ar.lproj/Welcome.strings new file mode 100644 index 000000000..75d5562b2 --- /dev/null +++ b/Resources/Resources/iOS/ar.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "سجل الدخول إلى حسابك"; +"login.username.placeholder" = "اسم المستخدم (p1234567)"; +"login.password.placeholder" = "كلمة المرور"; +"login.submit" = "تسجيل الدخول"; +"login.restore.button" = "لم تحصل على تفاصيل الحساب؟"; +"login.error.title" = "تسجيل الدخول"; +"login.error.validation" = "يجب إدخال اسم المستخدم وكلمة المرور"; +"login.error.unauthorized" = "اسم المستخدم أو كلمة المرور غير صحيحة."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "تسجيل الدخول باستخدام إيصال الشراء"; +"login.magic.link.title" = "تسجيل الدخول باستخدام رابط البريد الإلكتروني السحري"; +"login.magic.link.response" = "يرجى إلقاء نظرة على بريدك الإلكتروني للحصول على رابط تسجيل الدخول."; +"login.magic.link.send" = "إرسال الرابط"; +"login.magic.link.invalid.email" = "البريد الإلكتروني غير صحيح. يرجى إعادة المحاولة."; + +"purchase.title" = "حدد خطة VPN"; +"purchase.subtitle" = "ضمان استرداد المال لمدة 7 أيام"; +"purchase.email.placeholder" = "البريد الإلكتروني"; +"purchase.continue" = "متابعة"; +"purchase.login.footer" = "لديك حساب بالفعل؟"; +"purchase.login.button" = "تسجيل الدخول"; +"purchase.error.title" = "شراء"; +"purchase.error.validation" = "يجب إدخال عنوان بريد إلكتروني."; +"purchase.error.connectivity.title" = "فشل الاتصال"; +"purchase.error.connectivity.description" = "لم نتمكن من الوصول إلى منفذ الإنترنت الخاص. ربما بسبب اتصال ضعيف بالإنترنت أو خدماتنا موقوفة في بلدك."; +"purchase.confirm.form.email" = "يرجى إدخال بريدك الإلكتروني"; +"purchase.confirm.plan" = "أنت تشتري الآن خطة %@"; +"purchase.email.why" = "نحتاج إلى بريدك الإلكتروني لإرسال اسم المستخدم وكلمة المرور."; +"purchase.submit" = "إرسال"; +"purchase.or" = "أو"; + +"upgrade.header" = "مرحبًا بعودتك!"; +"upgrade.title" = "لاستخدام Private Internet Access، تحتاج إلى تجديد اشتراكك."; +"upgrade.renew.now" = "تجديد الآن"; + + + +"redeem.title" = "استلم محتويات بطاقة هدية"; +"redeem.subtitle" = "أدخل بريدك الإلكتروني ورمز بطاقة الهدية أو بطاقة التجربة المكون من %lu خانات."; +"redeem.email.placeholder" = "البريد الإلكتروني"; +"redeem.submit" = "إرسال"; +"redeem.error.title" = "استلام"; +"redeem.error.code" = "يجب أن يتكون الرمز من %lu خانات رقمية."; +"redeem.error.allfields" = "يرجى كتابة بريدك الإلكتروني ورمز PIN الخاص بالبطاقة."; +"redeem.accessibility.back" = "عودة"; +"redeem.giftcard.placeholder" = "رمز PIN الخاص بالبطاقة."; + +"plan.monthly.title" = "شهريًا"; +"plan.yearly.title" = "سنويًا"; +"plan.yearly.detail_format" = "%@%@ في السنة"; +"plan.price_format" = "%@ / شهر"; +"plan.best_value" = "أفضل قيمة"; +"plan.accessibility.per_month" = "في الشهر"; + +"restore.title" = "استرداد الشراء غير المقيد في الحساب"; +"restore.subtitle" = "إذا اشتريت خطة من خلال هذا التطبيق ولم تصلك بيانات تسجيل دخولك، يمكنك إرسالها مرة أخرى من هنا. لن يتم تحصيل رسوم منك أثناء هذه العملية."; +"restore.email.placeholder" = "البريد الإلكتروني"; +"restore.submit" = "تأكيد"; + +"iap.error.message.unavailable" = "خوادم أبل غير متاحة حاليًا. يرجى إعادة المحاولة لاحقًا."; +"iap.error.title" = "خطأ"; + +"agreement.trials.title" = "شروط وأحكام الفترات التجريبية المجانية"; +"agreement.trials.message" = "سيتم تحصيل مبلغ الدفع من حساب Apple ID الخاص بك عند تأكيد الشراء. يتم تجديد الاشتراك تلقائيًا ما لم يتم إلغاؤه قبل نهاية الفترة الحالية بمدة 24 ساعة على الأقل. سيتم محاسبتك على التجديد خلال 24 ساعة قبل نهاية الفترة الحالية. يمكنك إدارة وإلغاء اشتراكاتك عن طريق الانتقال إلى إعدادات حسابك في متجر التطبيقات بعد الشراء.\n\nقد توفر بعض الاشتراكات المدفوعة فترة تجريبية مجانية قبل تحصيل المبلغ من طريقة الدفع. إذا قررت إلغاء الاشتراك من اشتراك مدفوع قبل البدء في تحصيل الرسوم من طريقة الدفع، قم بإلغاء الاشتراك قبل انتهاء الفترة التجريبية المجانية بمدة 24 ساعة على الأقل.\n\nلا يتم توفير التجارب المجانية إلا للمستخدمين الجدد فقط، وهي وفقًا لتقديرنا الخاص، وإذا حاولت التسجيل للحصول على فترة تجريبية مجانية إضافية، فستتم محاسبتك فورًا على رسوم الاشتراك القياسية.\n\nنحن نحتفظ بالحق في إلغاء الفترة التجريبية المجانية في أي وقت.\n\nسيتم مصادرة أي جزء غير مستخدم من الفترة التجريبية المجانية عند شراء اشتراك.\n\nيمثل التسجيل قبولًا لهذه الشروط والأحكام."; +"agreement.message" = "بعد انتهاء الـ 7 أيام الخاصة بالفترة التجريبية المجانية، يتم تجديد هذا الاشتراك تلقائيًا مقابل %@ ما لم يتم إلغاؤه قبل 24 ساعة على الأقل من نهاية الفترة التجريبية. ستتم محاسبة حساب Apple ID الخاص بك على رسوم التجديد في غضون 24 ساعة قبل نهاية الفترة التجريبية. يمكنك إدارة وإلغاء اشتراكاتك عن طريق الانتقال إلى إعدادات حسابك في App Store بعد الشراء. يقتصر عرض الفترة التجريبية لمدة 7 أيام على عرض فترة تجريبية واحد لمدة 7 أيام لكل مستخدم. أي جزء غير مستخدم من الفترة التجريبية المجانية، إذا تم عرضها، سيتم مصادرته عندما يشتري المستخدم اشتراكًا. تشمل جميع الأسعار ضرائب المبيعات المحلية المطبقة.\n\nيعتبر الاشتراك بمثابة قبول $1 و$2."; +"agreement.trials.yearly.plan" = "سنة"; +"agreement.trials.monthly.plan" = "شهر"; + +"agreement.message.tos" = "شروط الخدمة"; +"agreement.message.privacy" = "سياسة الخصوصية"; + +"getstarted.buttons.buyaccount" = "شراء حساب"; + +"gdpr.collect.data.title" = "المعلومات الشخصية التي نجمعها"; +"gdpr.collect.data.description" = "عنوان البريد الإلكتروني لأغراض إدارة الحساب والحماية من إساءة الاستخدام."; +"gdpr.usage.data.title" = "استخدامات المعلومات الشخصية التي نجمعها"; +"gdpr.usage.data.description" = "يتم استخدام عنوان البريد الإلكتروني لإرسال معلومات الاشتراك وتأكيد الدفع ومراسلات العملاء والعروض الترويجية الخاصة بـ Private Internet Access فقط."; +"gdpr.accept.button.title" = "موافق ومتابعة"; + +"update.account.email.error" = "تعذَّر تعديل البريد الإلكتروني للحساب"; diff --git a/Resources/Resources/iOS/da.lproj/Signup.strings b/Resources/Resources/iOS/da.lproj/Signup.strings new file mode 100644 index 000000000..44c000115 --- /dev/null +++ b/Resources/Resources/iOS/da.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Bekræft tilmelding"; +"in_progress.message" = "Vi bekræfter dit køb i vores system. Det kan tage et øjeblik, så bliv her venligst."; +"in_progress.redeem.message" = "Vi bekræfter din kort-pinkode i vores system. Det kan tage et øjeblik, så bliv her venligst."; + +"success.title" = "Køb fuldført"; +"success.message_format" = "Tak fordi du tilmeldte dig hos os. Vi har sendt dit brugernavn og kodeord til din e-mailadresse %@"; +"success.redeem.title" = "Kort indløst med succes"; +"success.redeem.message" = "Du modtager snart en e-mail med dit brugernavn og adgangskode.\n\nDine loginoplysninger"; +"success.username.caption" = "Brugernavn"; +"success.password.caption" = "Kodeord"; +"success.submit" = "Kom i gang"; + +"failure.vc_title" = "Tilmelding mislykkedes"; +"failure.title" = "Kunne ikke oprette konto"; +"failure.message" = "Vi kan ikke oprette en konto på nuværende tidspunkt. Prøv igen senere.\n\nGenåbning af appen vil genoptage forsøget på at oprette en konto."; +"failure.purchase.sandbox.message" = "Det valgte sandbox-abonnement er ikke tilgængeligt i produktionen."; +"failure.redeem.invalid.title" = "Ugyldig kort-pinkode"; +"failure.redeem.invalid.message" = "Det ser ud til, at du har indtastet en ugyldig kort-pinkode. Prøv igen."; +"failure.redeem.claimed.title" = "Kort allerede taget"; +"failure.redeem.claimed.message" = "Det ser ud til, at dette kort allerede er taget af en anden konto. Prøv at indtaste en anden pinkode."; +"failure.submit" = "GÅ TILBAGE"; + +"unreachable.vc_title" = "Fejl"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Ingen internetforbindelse fundet. Bekræft venligst, at du har en internetforbindelse, og tryk på \"prøv igen\" herunder.\n\nDu kan vende tilbage til appen senere for at afslutte processen."; +"unreachable.submit" = "PRØV IGEN"; + +"purchase.uncredited.alert.message" = "Du har ukrediterede transaktioner. Vil du gendanne dine kontooplysninger?"; +"purchase.uncredited.alert.button.cancel" = "Annuller"; +"purchase.uncredited.alert.button.recover" = "Gendan konto"; + +"purchase.trials.intro" = "Start din 7-dages gratis prøveperiode"; +"purchase.trials.price.after" = "Derefter %@"; +"purchase.trials.money.back" = "30-dages pengene tilbage garanti"; +"purchase.trials.1year.protection" = "1 års beskyttelse af personlige oplysninger og identitet"; +"purchase.trials.anonymous" = "Gennemse anonymt og skjul din ip."; +"purchase.trials.devices" = "Understøtter 10 enheder på én gang"; +"purchase.trials.devices.description" = "Beskyt dig selv på op til 10 enheder ad gangen."; +"purchase.trials.region" = "Forbind nemt til en hvilken som helst region"; +"purchase.trials.servers" = "Mere end 3300 servere i 32 lande"; +"purchase.trials.start" = "Start abonnement"; +"purchase.trials.all.plans" = "Se alle tilgængelige planer"; + +"purchase.subscribe.now" = "Tilmeld nu"; + +// WALKTHROUGH + +"walkthrough.action.next" = "NÆSTE"; +"walkthrough.action.done" = "UDFØRT"; +"walkthrough.action.skip" = "SPRING OVER"; + +"walkthrough.page.1.title" = "Understøtter 10 enheder på en gang"; +"walkthrough.page.1.description" = "Beskyt dig selv på op til 10 enheder ad gangen."; +"walkthrough.page.2.title" = "Forbind nemt til en hvilken som helst region"; +"walkthrough.page.2.description" = "Med servere rundt om i verden er du altid beskyttet."; +"walkthrough.page.3.title" = "Beskyt dig mod annoncer"; +"walkthrough.page.3.description" = "Aktivering af vores Indholdsblokering forhindrer reklamer i at blive vist i Safari."; + +"share.data.buttons.accept" = "Accepter"; +"share.data.buttons.noThanks" = "Nej tak"; +"share.data.buttons.readMore" = "Læs mere"; +"share.data.text.title" = "Hjælp os med at forbedre vores service"; +"share.data.text.description" = "For at hjælpe os med at sikre vores tjenestes forbindelsesydelse, kan du anonymt dele dine forbindelsesstatistikker med os. Disse rapporter inkluderer ikke personligt identificerbare oplysninger."; +"share.data.text.footer" = "Du kan altid kontrollere dette fra dine indstillinger"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/da.lproj/Welcome.strings b/Resources/Resources/iOS/da.lproj/Welcome.strings new file mode 100644 index 000000000..6e179a032 --- /dev/null +++ b/Resources/Resources/iOS/da.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Log ind på din konto"; +"login.username.placeholder" = "Brugernavn (p1234567)"; +"login.password.placeholder" = "Kodeord"; +"login.submit" = "LOG IND"; +"login.restore.button" = "Modtog du ikke dine kontodetaljer?"; +"login.error.title" = "Log ind"; +"login.error.validation" = "Du skal indtaste et brugernavn og et kodeord."; +"login.error.unauthorized" = "Dit brugernavn eller kodeord er forkert."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Log på med købskvittering"; +"login.magic.link.title" = "Log ind ved hjælp af magisk e-maillink"; +"login.magic.link.response" = "Se i din e-mail for et login-link."; +"login.magic.link.send" = "Send link"; +"login.magic.link.invalid.email" = "Ugyldig e-mail. Prøv igen."; + +"purchase.title" = "Vælg en VPN-plan"; +"purchase.subtitle" = "30-dages pengene tilbage garanti"; +"purchase.email.placeholder" = "E-mailadresse"; +"purchase.continue" = "Fortsæt"; +"purchase.login.footer" = "Har du allerede en konto?"; +"purchase.login.button" = "Log ind"; +"purchase.error.title" = "Køb"; +"purchase.error.validation" = "Du skal indtaste en e-mailadresse"; +"purchase.error.connectivity.title" = "Forbindelsesfejl"; +"purchase.error.connectivity.description" = "Vi kan ikke nå Private Internet Access. Dette kan skyldes dårlig internet eller at vores service er blokeret i dit land."; +"purchase.confirm.form.email" = "Indtast din e-mailadresse"; +"purchase.confirm.plan" = "Du køber %@-planen"; +"purchase.email.why" = "Vi har brug for din e-mail for at sende dit brugernavn og din adgangskode."; +"purchase.submit" = "Indsend"; +"purchase.or" = "eller"; + +"upgrade.header" = "Velkommen tilbage!"; +"upgrade.title" = "For at bruge Private Internet Access skal du forny dit abonnement."; +"upgrade.renew.now" = "Forny nu"; + + + +"redeem.title" = "Indløs gavekort"; +"redeem.subtitle" = "Indtast din e-mailadresse, og %lu-cifrede pinkode frra dit gavekort eller prøvekort herunder."; +"redeem.email.placeholder" = "E-mailadresse"; +"redeem.submit" = "INDSEND"; +"redeem.error.title" = "Indløs"; +"redeem.error.code" = "Koden skal være %lu numeriske cifre."; +"redeem.error.allfields" = "Indtast venligst din e-mail og dit korts PIN-kode."; +"redeem.accessibility.back" = "Tilbage"; +"redeem.giftcard.placeholder" = "Gavekortets PIN-kode"; + +"plan.monthly.title" = "Månedligt"; +"plan.yearly.title" = "Årligt"; +"plan.yearly.detail_format" = "%@%@ per år"; +"plan.price_format" = "%@/mdr"; +"plan.best_value" = "Bedste værdi"; +"plan.accessibility.per_month" = "per måned"; + +"restore.title" = "Gendan ukrediteret køb"; +"restore.subtitle" = "Hvis du har købt en plan gennem denne app og ikke har modtaget dine legitimationsoplysninger, kan du anmode om at sende dem igen herfra. Du vil ikke blive opkrævet i løbet af denne proces."; +"restore.email.placeholder" = "E-mailadresse"; +"restore.submit" = "BEKRÆFT"; + +"iap.error.message.unavailable" = "Apple-servere er ikke tilgængelige i øjeblikket. Prøv venligst igen senere."; +"iap.error.title" = "Fejl"; + +"agreement.trials.title" = "Vilkår og betingelser for gratis prøveperioder"; +"agreement.trials.message" = "Betaling debiteres din Apple ID-konto ved bekræftelsen af ​​købet. Abonnementet fornyes automatisk, medmindre det annulleres mindst 24 timer inden udgangen af ​​den aktuelle periode. Din konto bliver debiteret for fornyelse inden for 24 timer inden udgangen af ​​den aktuelle periode. Du kan administrere og annullere dine abonnementer ved at gå til dine kontoindstillinger i App Store efter køb.\n\nVisse betalte abonnementer kan muligvis tilbyde en gratis prøveperiode, inden de opkræver din betalingsmetode. Hvis du beslutter at afmelde dig et betalt abonnement, før vi begynder at opkræve din betalingsmetode, skal du annullere abonnementet mindst 24 timer før den gratis prøveperiode afsluttes.\n\nGratis prøveperioder er kun tilgængelige for nye brugere og er efter vores eget skøn, og hvis du forsøger at tilmelde dig en ekstra gratis prøveperiode, bliver du straks debiteret for det almindelige abonnementsgebyr.\n\nVi forbeholder os retten til at tilbagekalde din gratis prøveperiode til enhver tid.\n\nEnhver ubrugt del af din gratis prøveperiode fortabes ved køb af et abonnement.\n\nTilmelding udgør accept af disse vilkår og betingelser."; +"agreement.message" = "Efter den gratis prøveperiode på 7 dage, fornyes dette abonnement automatisk for %@, medmindre det annulleres mindst 24 timer før prøveperioden er afsluttet. Din Apple ID-konto bliver debiteret for fornyelse inden for 24 timer inden udløbet af prøveperioden. Du kan administrere og annullere dine abonnementer ved at gå til din App Store-kontoindstillinger efter købet. Tilbudet med en 7-dages prøveperiode er begrænset til en 7-dages prøveperiode pr. bruger. Enhver ubrugt del af en gratis prøveperiode, hvis den tilbydes, fortabes, når brugeren køber et abonnement. Alle priser inkluderer gældende lokal moms.\n\nSigning up constitutes acceptance of the $1 and the $2."; +"agreement.trials.yearly.plan" = "år"; +"agreement.trials.monthly.plan" = "måned"; + +"agreement.message.tos" = "Vilkår for brug"; +"agreement.message.privacy" = "Fortrolighedspolitik"; + +"getstarted.buttons.buyaccount" = "Køb konto"; + +"gdpr.collect.data.title" = "Personlige oplysninger, vi indsamler"; +"gdpr.collect.data.description" = "E-mailadresse med henblik på kontohåndtering og beskyttelse mod misbrug."; +"gdpr.usage.data.title" = "Anvendelse af personlige oplysninger indsamlet af os"; +"gdpr.usage.data.description" = "E-mailadresse bruges kun til at sende abonnementsoplysninger, betalingsbekræftelser, kundekorrespondance og salgsfremmende tilbud fra Private Internet Access."; +"gdpr.accept.button.title" = "Accepter og fortsæt"; + +"update.account.email.error" = "Lykkedes ikke at ændre konto-e-mail"; diff --git a/Resources/Resources/iOS/de.lproj/Signup.strings b/Resources/Resources/iOS/de.lproj/Signup.strings new file mode 100644 index 000000000..ba5d2b2b5 --- /dev/null +++ b/Resources/Resources/iOS/de.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Registrierung bestätigen"; +"in_progress.message" = "Wir bestätigen deinen Kauf in unserem System. Es kann einen Moment dauern, also gedulde dich bitte etwas."; +"in_progress.redeem.message" = "Wir überprüfen derzeit Ihre Karten-PIN in unserem System. Dies kann einen Moment dauern. Bitte haben Sie etwas Geduld."; + +"success.title" = "Kauf abgeschlossen"; +"success.message_format" = "Vielen Dank für deine Registrierung. Wir haben dir deinen Benutzernamen und dein Passwort an deine E-Mail-Adresse unter %@ gesendet."; +"success.redeem.title" = "Karte erfolgreich eingelöst!"; +"success.redeem.message" = "Sie werden in Kürze eine E-Mail mit Ihrem Benutzernamen und Passwort erhalten.\n\nIhre Zugangsdaten"; +"success.username.caption" = "Benutzername"; +"success.password.caption" = "Passwort"; +"success.submit" = "Erste Schritte"; + +"failure.vc_title" = "Registrierung fehlgeschlagen"; +"failure.title" = "Konto nicht erstellt"; +"failure.message" = "Zur Zeit können wir kein Konto erstellen. Bitte später erneut versuchen.\n\nBeim erneuten Öffnen der App wird wieder versucht, ein Konto zu erstellen."; +"failure.purchase.sandbox.message" = "Das ausgewählte Sandbox-Abonnement ist in der Produktion nicht verfügbar."; +"failure.redeem.invalid.title" = "Ungültige Karten-PIN"; +"failure.redeem.invalid.message" = "Anscheinend haben Sie eine ungültige PIN eingegeben. Bitte erneut versuchen."; +"failure.redeem.claimed.title" = "Karte bereits eingelöst"; +"failure.redeem.claimed.message" = "Anscheinend wurde diese Karte bereits über ein anderes Konto eingelöst. Geben Sie eine andere PIN ein."; +"failure.submit" = "ZURÜCK"; + +"unreachable.vc_title" = "Fehler"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Keine Internetverbindung gefunden. Bitte deine Internetverbindung überprüfen und erneut versuchen.\n\nDu kannst die App später erneut aufrufen, um den Vorgang abzuschließen."; +"unreachable.submit" = "WIEDERHOLEN"; + +"purchase.uncredited.alert.message" = "Sie haben Transaktionen, die noch nicht gutgeschrieben wurden. Möchten Sie Ihre Kontodaten wiederherstellen?"; +"purchase.uncredited.alert.button.cancel" = "Abbrechen"; +"purchase.uncredited.alert.button.recover" = "Konto wiederherstellen"; + +"purchase.trials.intro" = "Jetzt 7 Tage gratis testen"; +"purchase.trials.price.after" = "Dann %@"; +"purchase.trials.money.back" = "30-Tage-Geld-zurück-Garantie"; +"purchase.trials.1year.protection" = "1 Jahr Daten- und Identitätsschutz"; +"purchase.trials.anonymous" = "Anonym surfen und Ihre IP-Adresse verbergen"; +"purchase.trials.devices" = "Unterstützung für 10 Geräte"; +"purchase.trials.devices.description" = "Schützen Sie sich auf bis zu 10 Geräten gleichzeitig."; +"purchase.trials.region" = "Einfache Verbindung zu jeder Region"; +"purchase.trials.servers" = "Mehr als 3300 Server in 32 Ländern"; +"purchase.trials.start" = "Abonnement beginnen"; +"purchase.trials.all.plans" = "Alle verfügbaren Pläne anzeigen"; + +"purchase.subscribe.now" = "Jetzt abonnieren"; + +// WALKTHROUGH + +"walkthrough.action.next" = "WEITER"; +"walkthrough.action.done" = "FERTIG"; +"walkthrough.action.skip" = "ÜBERSPRINGEN"; + +"walkthrough.page.1.title" = "Unterstützung für 10 Geräte"; +"walkthrough.page.1.description" = "Schützen Sie sich auf bis zu 10 Geräten gleichzeitig."; +"walkthrough.page.2.title" = "Bequem mit jeder beliebigen Region verbinden"; +"walkthrough.page.2.description" = "Mit Servern auf der ganzen Welt bist du immer geschützt."; +"walkthrough.page.3.title" = "Schütze dich vor Werbung"; +"walkthrough.page.3.description" = "Mit der Aktivierung unseres Inhalts-Blockers sehen Sie keine Anzeigen in Safari mehr."; + +"share.data.buttons.accept" = "Akzeptieren"; +"share.data.buttons.noThanks" = "Nein danke"; +"share.data.buttons.readMore" = "Mehr erfahren"; +"share.data.text.title" = "Bitte helfen Sie uns, unseren Service zu verbessern"; +"share.data.text.description" = "Um uns zu helfen, die Verbindungsleistung unseres Dienstes sicherzustellen, können Sie Ihre Verbindungsstatistiken anonym mit uns teilen. Diese Berichte enthalten keine persönlich identifizierbaren Informationen."; +"share.data.text.footer" = "Sie können dies jederzeit über Ihre Einstellungen steuern"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/de.lproj/Welcome.strings b/Resources/Resources/iOS/de.lproj/Welcome.strings new file mode 100644 index 000000000..ed13eb4ab --- /dev/null +++ b/Resources/Resources/iOS/de.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "An deinem Konto anmelden"; +"login.username.placeholder" = "Benutzername (p1234567)"; +"login.password.placeholder" = "Passwort"; +"login.submit" = "ANMELDEN"; +"login.restore.button" = "Keine Kontodaten erhalten?"; +"login.error.title" = "Anmelden"; +"login.error.validation" = "Du musst einen Benutzernamen und ein Passwort angeben."; +"login.error.unauthorized" = "Dein Benutzername oder Passwort ist falsch."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Anmeldung mit Kaufbeleg"; +"login.magic.link.title" = "Anmeldung mit magischem E-Mail-Link"; +"login.magic.link.response" = "Bitte überprüfen Sie Ihre E-Mail auf einen Login-Link."; +"login.magic.link.send" = "Link senden"; +"login.magic.link.invalid.email" = "Ungültige E-Mail-Adresse. Bitte erneut versuchen."; + +"purchase.title" = "VPN-Tarif auswählen"; +"purchase.subtitle" = "30-Tage-Geld-zurück-Garantie"; +"purchase.email.placeholder" = "E-Mail-Adresse"; +"purchase.continue" = "Weiter"; +"purchase.login.footer" = "Bereits ein Konto?"; +"purchase.login.button" = "Anmelden"; +"purchase.error.title" = "Kaufen"; +"purchase.error.validation" = "Sie müssen eine E-Mail-Adresse angeben."; +"purchase.error.connectivity.title" = "Verbindungsfehler"; +"purchase.error.connectivity.description" = "Wir können Private Internet Access nicht erreichen. Dies kann auf eine schlechte Internetverbindung zurückzuführen sein oder unser Service ist in deinem Land blockiert."; +"purchase.confirm.form.email" = "E-Mail-Adresse eingeben"; +"purchase.confirm.plan" = "Sie erwerben den %@-Tarif."; +"purchase.email.why" = "Wir benötigen Ihre E-Mail, um Ihren Benutzernamen und Ihr Passwort zu senden."; +"purchase.submit" = "Senden"; +"purchase.or" = "oder"; + +"upgrade.header" = "Willkommen zurück!"; +"upgrade.title" = "Sie müssen Ihr Abonnement erneuern, um Private Internet Access nutzen zu können."; +"upgrade.renew.now" = "Jetzt erneuern"; + + + +"redeem.title" = "Geschenkkarte einlösen"; +"redeem.subtitle" = "Geben Sie unten Ihre E-Mail-Adresse und die %lu-stellige PIN von Ihrer Geschenk- oder Testkarte ein."; +"redeem.email.placeholder" = "E-Mail-Adresse"; +"redeem.submit" = "SENDEN"; +"redeem.error.title" = "Einlösen"; +"redeem.error.code" = "Der Code muss aus %lu Ziffern bestehen."; +"redeem.error.allfields" = "Bitte geben Sie Ihre E-Mail-Adresse und Karten-PIN ein."; +"redeem.accessibility.back" = "Zurück"; +"redeem.giftcard.placeholder" = "PIN der Geschenkkarte"; + +"plan.monthly.title" = "Monatlich"; +"plan.yearly.title" = "Jährlich"; +"plan.yearly.detail_format" = "%@%@ pro Jahr"; +"plan.price_format" = "%@/Monat"; +"plan.best_value" = "Bestpreis"; +"plan.accessibility.per_month" = "pro Monat"; + +"restore.title" = "Nicht gutgeschriebenen Kauf wiederherstellen"; +"restore.subtitle" = "Wenn Sie einen Tarif über diese App erworben haben und Ihre Zugangsdaten nicht erhalten haben, können Sie sie hier erneut anfordern. Sie müssen dann nicht erneut bezahlen."; +"restore.email.placeholder" = "E-Mail-Adresse"; +"restore.submit" = "BESTÄTIGEN"; + +"iap.error.message.unavailable" = "Die Apple-Server sind momentan nicht verfügbar. Bitte später erneut versuchen."; +"iap.error.title" = "Fehler"; + +"agreement.trials.title" = "Nutzungsbedingungen für kostenlose Testversionen"; +"agreement.trials.message" = "Die Zahlung wird Ihrem Apple ID-Konto bei der Kaufbestätigung belastet. Das Abonnement verlängert sich automatisch, wenn es nicht mindestens 24 Stunden vor Ablauf der aktuellen Periode gekündigt wird. Die Verlängerung wird Ihrem Konto innerhalb von 24 Stunden vor Ablauf der aktuellen Periode in Rechnung gestellt. Sie können Ihre Abonnements verwalten und kündigen, indem Sie nach dem Kauf zu Ihren Kontoeinstellungen im App Store aufrufen.\n\nBestimmte kostenpflichtige Abonnements können eine kostenlose Testversion anbieten, bevor Sie Ihre Zahlungsmethode berechnen. Wenn Sie sich entscheiden, sich von einem kostenpflichtigen Abonnement abzumelden, bevor wir mit der Berechnung Ihrer Zahlungsmethode beginnen, kündigen Sie das Abonnement mindestens 24 Stunden vor Ablauf der kostenlosen Probezeit.\n\nKostenlose Testversionen sind nur für neue Benutzer verfügbar und liegen in unserem alleinigen Ermessen, und wenn Sie versuchen, sich für eine zusätzliche kostenlose Testversion anzumelden, wird Ihnen sofort die Standard-Abonnementgebühr in Rechnung gestellt.\n\nWir behalten uns das Recht vor, Ihre kostenlose Testversion jederzeit zu widerrufen.\n\nJeder ungenutzte Teil Ihrer kostenlosen Probezeit verfällt mit dem Kauf eines Abonnements.\n\nMit der Registrierung akzeptieren Sie diese Nutzungsbedingungen."; +"agreement.message" = "Nach der 7-tägigen kostenlosen Testperiode verlängert sich dieses Abonnement automatisch für %@, sofern es nicht mindestens 24 Stunden vor Ablauf der Testperiode gekündigt wird. Ihr Apple-ID-Konto wird für die Verlängerung innerhalb von 24 Stunden vor Ablauf des Testzeitraums belastet. Sie können Ihre Abonnements nach dem Kauf in den Einstellungen Ihres App Store-Kontos verwalten und kündigen. Jeder Benutzer kann die 7-tägige kostenlose Testperiode nur einmal in Anspruch nehmen. Jeder nicht genutzte Teil einer kostenlosen Testperiode, falls angeboten, verfällt beim Kauf eines Abonnements durch den Benutzer. Alle Preise enthalten die örtlich geltenden Verkaufssteuern.\n\nMit der Anmeldung akzeptieren Sie die $1 und $2."; +"agreement.trials.yearly.plan" = "Jahr"; +"agreement.trials.monthly.plan" = "Monat"; + +"agreement.message.tos" = "Nutzungsbedingungen"; +"agreement.message.privacy" = "Datenschutzrichtlinien"; + +"getstarted.buttons.buyaccount" = "Konto kaufen"; + +"gdpr.collect.data.title" = "Art der personenbezogenen Daten, die wir erfassen"; +"gdpr.collect.data.description" = "E-Mail-Adresse zum Zwecke der Kontoverwaltung und zum Schutz vor Missbrauch."; +"gdpr.usage.data.title" = "Verwendungszwecke für personenbezogene Daten, die von uns erfasst wurden"; +"gdpr.usage.data.description" = "Die E-Mail-Adresse wird lediglich zum Senden von Abonnementinformationen, Zahlungsbestätigungen, Kundenkorrespondenz und Sonderangeboten zu Private Internet Access verwendet."; +"gdpr.accept.button.title" = "Zustimmen und fortfahren"; + +"update.account.email.error" = "Konto-E-Mail nicht geändert"; diff --git a/Resources/Resources/iOS/en.lproj/Signup.strings b/Resources/Resources/iOS/en.lproj/Signup.strings new file mode 100644 index 000000000..dacff3d57 --- /dev/null +++ b/Resources/Resources/iOS/en.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirm sign-up"; +"in_progress.message" = "We're confirming your purchase with our system. It could take a moment so hang in there."; +"in_progress.redeem.message" = "We're confirming your card PIN with our system. It could take a moment so hang in there."; + +"success.title" = "Purchase complete"; +"success.message_format" = "Thank you for signing up with us. We have sent your account username and password at your email address at %@"; +"success.redeem.title" = "Card redeemed successfully"; +"success.redeem.message" = "You will receive an email shortly with your username and password.\n\nYour login details"; +"success.username.caption" = "Username"; +"success.password.caption" = "Password"; +"success.submit" = "GET STARTED"; + +"failure.vc_title" = "Sign-up failed"; +"failure.title" = "Account creation failed"; +"failure.message" = "We're unable to create an account at this time. Please try again later. Reopening the app will re-attempt to create an account."; +"failure.purchase.sandbox.message" = "The selected sandbox subscription is not available in production."; +"failure.redeem.invalid.title" = "Invalid card PIN"; +"failure.redeem.invalid.message" = "Looks like you entered an invalid card PIN. Please try again."; +"failure.redeem.claimed.title" = "Card claimed already"; +"failure.redeem.claimed.message" = "Looks like this card has already been claimed by another account. You can try entering a different PIN."; +"failure.submit" = "GO BACK"; + +"unreachable.vc_title" = "Error"; +"unreachable.title" = "Whoops!"; +"unreachable.message" = "No internet connection found. Please confirm that you have an internet connection and hit retry below.\n\nYou can come back to the app later to finish the process."; +"unreachable.submit" = "TRY AGAIN"; + +"purchase.uncredited.alert.message" = "You have uncredited transactions. Do you want to recover your account details?"; +"purchase.uncredited.alert.button.cancel" = "Cancel"; +"purchase.uncredited.alert.button.recover" = "Recover account"; + +"purchase.trials.intro" = "Start your 7-day free trial"; +"purchase.trials.price.after" = "Then %@"; +"purchase.trials.money.back" = "30 day money back guarantee"; +"purchase.trials.1year.protection" = "1 year of privacy and identity protection"; +"purchase.trials.anonymous" = "Browse anonymously and hide your ip."; +"purchase.trials.devices" = "Support 10 devices at once"; +"purchase.trials.devices.description" = "Protect yourself on up to 10 devices at a time."; +"purchase.trials.region" = "Connect to any region easily"; +"purchase.trials.servers" = "More than 3300 servers in 32 countries"; +"purchase.trials.start" = "Start subscription"; +"purchase.trials.all.plans" = "See all available plans"; + +"purchase.subscribe.now" = "Subscribe now"; + +// WALKTHROUGH + +"walkthrough.action.next" = "NEXT"; +"walkthrough.action.done" = "DONE"; +"walkthrough.action.skip" = "SKIP"; + +"walkthrough.page.1.title" = "Support 10 devices at once"; +"walkthrough.page.1.description" = "Protect yourself on up to 10 devices at a time."; +"walkthrough.page.2.title" = "Connect to any region easily"; +"walkthrough.page.2.description" = "With servers around the globe, you are always under protection."; +"walkthrough.page.3.title" = "Protect yourself from ads"; +"walkthrough.page.3.description" = "Enabling our Content Blocker prevents ads from showing in Safari."; + +"share.data.buttons.accept" = "Accept"; +"share.data.buttons.noThanks" = "No, thanks"; +"share.data.buttons.readMore" = "Read more"; +"share.data.text.title" = "Please help us improve our service"; +"share.data.text.description" = "To help us ensure our service's connection performance, you can anonymously share your connection stats with us. These reports do not include any personally identifiable information."; +"share.data.text.footer" = "You can always control this from your settings"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/en.lproj/Welcome.strings b/Resources/Resources/iOS/en.lproj/Welcome.strings new file mode 100644 index 000000000..91c5c4c53 --- /dev/null +++ b/Resources/Resources/iOS/en.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Sign in to your account"; +"login.username.placeholder" = "Username (p1234567)"; +"login.password.placeholder" = "Password"; +"login.submit" = "LOGIN"; +"login.restore.button" = "Didn't receive account details?"; +"login.error.title" = "Log in"; +"login.error.validation" = "You must enter a username and password."; +"login.error.unauthorized" = "Your username or password is incorrect."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Login using purchase receipt"; +"login.magic.link.title" = "Login using magic email link"; +"login.magic.link.response" = "Please check your e-mail for a login link."; +"login.magic.link.send" = "Send Link"; +"login.magic.link.invalid.email" = "Invalid email. Please try again."; + +"purchase.title" = "Select a VPN plan"; +"purchase.subtitle" = "30-day money back guarantee"; +"purchase.email.placeholder" = "Email address"; +"purchase.continue" = "Continue"; +"purchase.login.footer" = "Already have an account?"; +"purchase.login.button" = "Sign in"; +"purchase.error.title" = "Purchase"; +"purchase.error.validation" = "You must enter an email address."; +"purchase.error.connectivity.title" = "Connection Failure"; +"purchase.error.connectivity.description" = "We are unable to reach Private Internet Access. This may due to poor internet or our service is blocked in your country."; +"purchase.confirm.form.email" = "Enter your email address"; +"purchase.confirm.plan" = "You are purchasing the %@ plan"; +"purchase.email.why" = "We need your email to send your username and password."; +"purchase.submit" = "Submit"; +"purchase.or" = "or"; + +"upgrade.header" = "Welcome Back!"; +"upgrade.title" = "In order to use Private Internet Access, you’ll need to renew your subscription."; +"upgrade.renew.now" = "Renew now"; + + + +"redeem.title" = "Redeem gift card"; +"redeem.subtitle" = "Type in your email address and the %lu digit PIN from your gift card or trial card below."; +"redeem.email.placeholder" = "Email address"; +"redeem.submit" = "SUBMIT"; +"redeem.error.title" = "Redeem"; +"redeem.error.code" = "Code must be %lu numeric digits."; +"redeem.error.allfields"="Please type in your email and card PIN."; +"redeem.accessibility.back" = "Back"; +"redeem.giftcard.placeholder" = "Gift card PIN"; + +"plan.monthly.title" = "Monthly"; +"plan.yearly.title" = "Yearly"; +"plan.yearly.detail_format" = "%@%@ per year"; +"plan.price_format" = "%@/mo"; +"plan.best_value" = "Best value"; +"plan.accessibility.per_month" = "per month"; + +"restore.title" = "Restore uncredited purchase"; +"restore.subtitle" = "If you purchased a plan through this app and didn't receive your credentials, you can send them again from here. You will not be charged during this process."; +"restore.email.placeholder" = "Email address"; +"restore.submit" = "CONFIRM"; + +"iap.error.message.unavailable" = "Apple servers currently unavailable. Please try again later."; +"iap.error.title" = "Error"; + +"agreement.trials.title" = "Free trials terms and conditions"; +"agreement.trials.message" = "Payment will be charged to your Apple ID account at the confirmation of purchase. Subscription automatically renews unless it is canceled at least 24 hours before the end of the current period. Your account will be charged for renewal within 24 hours prior to the end of the current period. You can manage and cancel your subscriptions by going to your account settings on the App Store after purchase.\n\nCertain Paid Subscriptions may offer a free trial prior to charging your payment method. If you decide to unsubscribe from a Paid Subscription before we start charging your payment method, cancel the subscription at least 24 hours before the free trial ends.\n\nFree trials are only available to new users, and are at our sole discretion, and if you attempt to sign up for an additional free trial, you will be immediately charged with the standard Subscription Fee.\n\nWe reserve the right to revoke your free trial at any time.\n\nAny unused portion of your free trial period will be forfeited upon purchase of a subscription.\n\nSigning up constitutes acceptance of this terms and conditions."; +"agreement.message" = "After the 7 days free trial this subscription automatically renews for %@ unless it is canceled at least 24 hours before the end of the trial period. Your Apple ID account will be charged for renewal within 24 hours before the end of the trial period. You can manage and cancel your subscriptions by going to your App Store account settings after purchase. 7-days trial offer is limited to one 7-days trial offer per user. Any unused portion of a free trial period, if offered, will be forfeited when the user purchases a subscription. All prices include applicable local sales taxes.\n\nSigning up constitutes acceptance of the $1 and the $2."; +"agreement.trials.yearly.plan" = "year"; +"agreement.trials.monthly.plan" = "month"; + +"agreement.message.tos" = "Terms of Service"; +"agreement.message.privacy" = "Privacy Policy"; + +"getstarted.buttons.buyaccount" = "Buy account"; + +"gdpr.collect.data.title" = "Personal information we collect"; +"gdpr.collect.data.description" = "E-mail Address for the purposes of account management and protection from abuse."; +"gdpr.usage.data.title" = "Uses of personal information collected by us"; +"gdpr.usage.data.description" = "E-mail address is used to send subscription information, payment confirmations, customer correspondence, and Private Internet Access promotional offers only."; +"gdpr.accept.button.title" = "Agree and continue"; + +"update.account.email.error" = "Failed to modify account email"; diff --git a/Resources/Resources/iOS/es-MX.lproj/Signup.strings b/Resources/Resources/iOS/es-MX.lproj/Signup.strings new file mode 100644 index 000000000..3ebdb9fd3 --- /dev/null +++ b/Resources/Resources/iOS/es-MX.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirmar registro"; +"in_progress.message" = "Estamos confirmando la compra en el sistema. Podrías tardar unos instantes, así que espera."; +"in_progress.redeem.message" = "Estamos confirmando el PIN de tu tarjeta en nuestro sistema. Puede tardar un momento, así que espera un poco."; + +"success.title" = "Compra completa"; +"success.message_format" = "Gracias por registrarte con nosotros. Te enviamos el nombre de usuario y contraseña de tu cuenta a tu dirección de email en %@"; +"success.redeem.title" = "Tarjeta canjeada correctamente"; +"success.redeem.message" = "Recibirás un mensaje de correo electrónico dentro de poco con tu nombre de usuario y contraseña.\n\nTu información de inicio de sesión"; +"success.username.caption" = "Nombre de usuario"; +"success.password.caption" = "Contraseña "; +"success.submit" = "Empieza"; + +"failure.vc_title" = "Falló el registro"; +"failure.title" = "Falló la creación de la cuenta"; +"failure.message" = "No pudimos crear una cuenta en este momento. Por favor, inténtalo de nuevo más tarde. \nSi vuelves a abrir la aplicación intentaremos crear una cuenta otra vez."; +"failure.purchase.sandbox.message" = "La suscripción del entorno aislado seleccionado no está disponible en la producción."; +"failure.redeem.invalid.title" = "El PIN de la tarjeta no es válido"; +"failure.redeem.invalid.message" = "Parece que ingresaste un PIN de tarjeta inválido. Por favor, inténtalo de nuevo."; +"failure.redeem.claimed.title" = "La tarjeta ya fue reclamada"; +"failure.redeem.claimed.message" = "Parece que esta tarjeta ha sido reclamada por otra cuenta. Puedes intentar ingresar un PIN diferente."; +"failure.submit" = "ATRÁS"; + +"unreachable.vc_title" = "Error"; +"unreachable.title" = "¡Ups!"; +"unreachable.message" = "No se encontró conexión a Internet. Por favor, confirma que tienes una conexión a Internet y toca en intentar de nuevo más abajo.\n\nPuedes regresar después a la aplicación para terminar el proceso."; +"unreachable.submit" = "VOLVER A INTENTAR"; + +"purchase.uncredited.alert.message" = "Tienes transacciones sin acreditar. ¿Seguro que quieres recuperar los detalles de tu cuenta?"; +"purchase.uncredited.alert.button.cancel" = "Cancelar"; +"purchase.uncredited.alert.button.recover" = "Recuperar cuenta"; + +"purchase.trials.intro" = "Inicia tu prueba gratuita de 7 días"; +"purchase.trials.price.after" = "Después, %@"; +"purchase.trials.money.back" = "Garantía de devolución de 30 días"; +"purchase.trials.1year.protection" = "1 año de privacidad y protección de la identidad."; +"purchase.trials.anonymous" = "Navega de forma anónima y oculta tu IP."; +"purchase.trials.devices" = "Admite 10 dispositivos a la vez."; +"purchase.trials.devices.description" = "Protégete en hasta 10 dispositivos a la vez."; +"purchase.trials.region" = "Conéctate a cualquier región con facilidad."; +"purchase.trials.servers" = "Más de 3300 servidores en 32 países."; +"purchase.trials.start" = "Iniciar suscripción"; +"purchase.trials.all.plans" = "Ver todos los planes disponibles."; + +"purchase.subscribe.now" = "Suscríbete ahora"; + +// WALKTHROUGH + +"walkthrough.action.next" = "SIGUIENTE"; +"walkthrough.action.done" = "TERMINADO"; +"walkthrough.action.skip" = "OMITIR"; + +"walkthrough.page.1.title" = "Admite 10 dispositivos a la vez"; +"walkthrough.page.1.description" = "Protégete en hasta 10 dispositivos a la vez."; +"walkthrough.page.2.title" = "Conéctate a cualquier región con facilidad"; +"walkthrough.page.2.description" = "Con servidores en todo el mundo, siempre estarás protegido."; +"walkthrough.page.3.title" = "Protégete de la publicidad"; +"walkthrough.page.3.description" = "Habilita nuestro Bloqueador de contenido para impedir que aparezca publicidad en Safari."; + +"share.data.buttons.accept" = "Aceptar"; +"share.data.buttons.noThanks" = "No, gracias"; +"share.data.buttons.readMore" = "Más información"; +"share.data.text.title" = "Ayúdanos a mejorar nuestro servicio."; +"share.data.text.description" = "Para ayudarnos a garantizar el rendimiento de la conexión de nuestro servicio, puedes compartir con nosotros tus estadísticas de conexión de forma anónima. Estos informes no contienen ninguna información personal identificable."; +"share.data.text.footer" = "Siempre puedes controlarlo desde tus ajustes."; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/es-MX.lproj/Welcome.strings b/Resources/Resources/iOS/es-MX.lproj/Welcome.strings new file mode 100644 index 000000000..3c47f73e3 --- /dev/null +++ b/Resources/Resources/iOS/es-MX.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Inicia sesión en tu cuenta"; +"login.username.placeholder" = "Nombre de usuario (p1234567)"; +"login.password.placeholder" = "Contraseña "; +"login.submit" = "INICIAR SESIÓN"; +"login.restore.button" = "¿No has recibido los detalles de la cuenta?"; +"login.error.title" = "Iniciar sesión"; +"login.error.validation" = "Debe ingresar un nombre de usuario y una contraseña."; +"login.error.unauthorized" = "Tu nombre de usuario o contraseña son incorrectos."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Inicia sesión con el recibo de compra"; +"login.magic.link.title" = "Inicia sesión con el vínculo mágico del correo electrónico."; +"login.magic.link.response" = "Busca en tu correo electrónico un enlace de inicio de sesión."; +"login.magic.link.send" = "Enviar enlace"; +"login.magic.link.invalid.email" = "Correo electrónico no válido. Vuelve a intentarlo."; + +"purchase.title" = "Selecciona un plan VPN"; +"purchase.subtitle" = "Garantía de devolución de 30 días"; +"purchase.email.placeholder" = "Dirección de correo electrónico"; +"purchase.continue" = "Continuar"; +"purchase.login.footer" = "¿Ya tienes una cuenta?"; +"purchase.login.button" = "Inicia sesión"; +"purchase.error.title" = "Comprar"; +"purchase.error.validation" = "Debes ingresar una dirección de email."; +"purchase.error.connectivity.title" = "Falla en la conexión"; +"purchase.error.connectivity.description" = "No pudimos localizar a Private Internet Access. Esto puede ser debido a una mala conexión con Internet o a que nuestro servicio está bloqueado en su país."; +"purchase.confirm.form.email" = "Introduce tu dirección de correo electrónico"; +"purchase.confirm.plan" = "Estás comprando el plan %@."; +"purchase.email.why" = "Necesitamos tu dirección de correo electrónico para enviar tu nombre de usuario y tu contraseña."; +"purchase.submit" = "Enviar"; +"purchase.or" = "o"; + +"upgrade.header" = "¡Hola otra vez!"; +"upgrade.title" = "Para usar Private Internet Access debes renovar tu suscripción."; +"upgrade.renew.now" = "Renovar ahora"; + + + +"redeem.title" = "Canjear tarjeta de regalo"; +"redeem.subtitle" = "Escribe abajo tu dirección de correo electrónico y el PIN de %lu dígitos de tu tarjeta de regalo o tarjeta de prueba."; +"redeem.email.placeholder" = "Dirección de correo electrónico"; +"redeem.submit" = "ENVIAR"; +"redeem.error.title" = "Canjear"; +"redeem.error.code" = "El código debe tener %lu dígitos numéricos."; +"redeem.error.allfields" = "Escribe tu dirección de correo electrónico y el PIN de tu tarjeta."; +"redeem.accessibility.back" = "Volver"; +"redeem.giftcard.placeholder" = "PIN de tarjeta regalo"; + +"plan.monthly.title" = "Mensual"; +"plan.yearly.title" = "Anual"; +"plan.yearly.detail_format" = "%@%@ al año"; +"plan.price_format" = "%@/m"; +"plan.best_value" = "Mejor oferta"; +"plan.accessibility.per_month" = "por mes"; + +"restore.title" = "Restablecer compra no acreditada"; +"restore.subtitle" = "Si compraste un plan a través de esta aplicación y no recibes tus credenciales, puedes reiniciar la renovación desde aquí. No se realizarán cargos durante este proceso. \n"; +"restore.email.placeholder" = "Correo electrónico"; +"restore.submit" = "CONFIRMAR"; + +"iap.error.message.unavailable" = "Actualmente, los servidores de Apple no están disponibles. Por favor, inténtalo de nuevo más tarde."; +"iap.error.title" = "Error"; + +"agreement.trials.title" = "Términos y condiciones de la prueba gratuita."; +"agreement.trials.message" = "Se realizará un cobro en tu cuenta de Apple ID en el momento de confirmar la compra. Las suscripciones se renuevan automáticamente a menos que se cancelen como mínimo 24 horas antes de la finalización del periodo actual. Se cobrará la cantidad de la renovación en un plazo de 24 horas antes de la finalización del período actual. Tu mismo podrás gestionar y cancelar las suscripciones en los ajustes de App Store después de la compra. \n\nAlgunas suscripciones de pago pueden ofrecer una prueba gratuita antes de realizar cobros según tu método de pago. Si decides darte de baja de una suscripción de pago antes de que comencemos a cobrar tu método de pago, cancela la suscripción al menos 24 horas antes de que finalice la prueba gratuita.\n\nLas pruebas gratuitas solo están disponibles para nuevos usuarios y quedan a nuestra entera discreción. Si intentas registrarte para obtener una prueba gratuita adicional, se te cobrará de inmediato la tarifa de suscripción estándar.\n\nNos reservamos el derecho de revocar tu prueba gratuita en cualquier momento.\n\nLas secciones sin usar del periodo de prueba gratuito se perderán si el usuario compra una suscripción.\n\nSi te registras, aceptas estos términos y condiciones."; +"agreement.message" = "Después de los 7 días de prueba gratuita, esta suscripción se renueva automáticamente por %@ a menos que se cancele al menos 24 horas antes del final del período de prueba. Se cobrará la renovación en tu cuenta de ID de Apple en un plazo de 24 horas antes de que finalice el periodo de prueba. Puedes gestionar y cancelar tus suscripciones accediendo a los ajustes de tu cuenta de App Store después de la compra. La oferta de prueba de 7 días se limita a una oferta de prueba de 7 días por usuario. Cualquier parte no utilizada de un período de prueba gratuito, si se ofrece, se perderá cuando el usuario compre una suscripción. Todos los precios incluyen los impuestos de venta locales aplicables.\n\nSi te registras, aceptas los $1 y la $2."; +"agreement.trials.yearly.plan" = "año"; +"agreement.trials.monthly.plan" = "mes"; + +"agreement.message.tos" = "Términos de servicio"; +"agreement.message.privacy" = "Política de privacidad"; + +"getstarted.buttons.buyaccount" = "Comprar cuenta"; + +"gdpr.collect.data.title" = "Información personal que recopilamos"; +"gdpr.collect.data.description" = "Dirección de correo electrónico con fines de gestión de cuenta y protección frente a abusos."; +"gdpr.usage.data.title" = "Usos de la información personal que recopilamos"; +"gdpr.usage.data.description" = "La dirección de correo electrónico solo se usa para enviar información de suscripción, confirmaciones de pago, correspondencia al cliente y ofertas promocionales de Private Internet Access."; +"gdpr.accept.button.title" = "Aceptar y continuar"; + +"update.account.email.error" = "Error al modificar el correo electrónico de la cuenta"; diff --git a/Resources/Resources/iOS/fr.lproj/Signup.strings b/Resources/Resources/iOS/fr.lproj/Signup.strings new file mode 100644 index 000000000..a99c30197 --- /dev/null +++ b/Resources/Resources/iOS/fr.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirmation d'inscription"; +"in_progress.message" = "Notre système est en train de confirmer votre achat. Cela pourrait prendre un moment, nous vous prions donc de patienter."; +"in_progress.redeem.message" = "Notre système est en train de confirmer le code PIN de votre carte. Cela pourrait prendre un moment, nous vous prions donc de patienter."; + +"success.title" = "Achat terminé"; +"success.message_format" = "Merci pour votre inscription. L'identifiant et le mot de passe de votre compte ont été envoyés à votre adresse e-mail %@"; +"success.redeem.title" = "Carte échangée avec succès"; +"success.redeem.message" = "Vous allez bientôt recevoir un e-mail contenant votre nom d'utilisateur et votre mot de passe.\n\nDétails de vos identifiants"; +"success.username.caption" = "Nom d'utilisateur"; +"success.password.caption" = "Mot de passe"; +"success.submit" = "Commencer"; + +"failure.vc_title" = "Échec de la connexion"; +"failure.title" = "La création du compte a échoué"; +"failure.message" = "Nous ne parvenons pas à créer un compte pour l'instant. Veuillez réessayer plus tard. \n\nRouvrir l'application engendrera une nouvelle tentative de création de compte."; +"failure.purchase.sandbox.message" = "L'abonnement sandbox sélectionné n'est pas disponible en production."; +"failure.redeem.invalid.title" = "Code PIN de la carte invalide"; +"failure.redeem.invalid.message" = "Il semblerait que le code PIN de la carte saisie soit invalide. Veuillez réessayer."; +"failure.redeem.claimed.title" = "Carte déjà utilisée"; +"failure.redeem.claimed.message" = "Il semblerait que cette carte soit déjà utilisée sur un autre compte. Vous pouvez essayer de saisir un code PIN différent."; +"failure.submit" = "REVENIR"; + +"unreachable.vc_title" = "Erreur"; +"unreachable.title" = "Oups !"; +"unreachable.message" = "Aucune connexion Internet trouvée. Veuillez confirmer que vous disposez d'une connexion Internet et cliquez de nouveau sur « Réessayer » ci-dessous.\n\nVous pourrez revenir dans l'application plus tard pour terminer le processus."; +"unreachable.submit" = "RÉESSAYER"; + +"purchase.uncredited.alert.message" = "Vous avez des transaction non créditées. Voulez-vous restaurer les détails de votre compte ?"; +"purchase.uncredited.alert.button.cancel" = "Annuler"; +"purchase.uncredited.alert.button.recover" = "Restaurer le compte"; + +"purchase.trials.intro" = "Démarrez votre essai gratuit de 7 jours"; +"purchase.trials.price.after" = "Ensuite %@"; +"purchase.trials.money.back" = "Garantie satisfait ou remboursé sur 30 jours"; +"purchase.trials.1year.protection" = "1 an de confidentialité et de protection de l'identité"; +"purchase.trials.anonymous" = "Surfez anonymement et masquez votre IP."; +"purchase.trials.devices" = "Prise en charge de 10 appareils en même temps"; +"purchase.trials.devices.description" = "Protégez-vous sur jusqu'à 10 appareils en même temps."; +"purchase.trials.region" = "Connectez-vous facilement à n'importe quelle région"; +"purchase.trials.servers" = "Plus de 3300 serveurs dans 32 pays"; +"purchase.trials.start" = "Commencer l'abonnement"; +"purchase.trials.all.plans" = "Voir tous les forfaits disponibles"; + +"purchase.subscribe.now" = "S'abonner maintenant"; + +// WALKTHROUGH + +"walkthrough.action.next" = "SUIVANT"; +"walkthrough.action.done" = "TERMINÉ"; +"walkthrough.action.skip" = "PASSER"; + +"walkthrough.page.1.title" = "Prend en charge 10 appareils en même temps"; +"walkthrough.page.1.description" = "Protégez-vous sur jusqu'à 10 appareils à la fois."; +"walkthrough.page.2.title" = "Connectez-vous facilement à n'importe quelle région"; +"walkthrough.page.2.description" = "Avec des serveurs partout dans le monde, vous êtes toujours sous protection."; +"walkthrough.page.3.title" = "Protégez-vous contre les publicités"; +"walkthrough.page.3.description" = "Activer notre bloqueur de contenu empêche les publicités de s'afficher dans Safari."; + +"share.data.buttons.accept" = "Accepter"; +"share.data.buttons.noThanks" = "Non, merci"; +"share.data.buttons.readMore" = "Lire plus"; +"share.data.text.title" = "Merci de nous aider à améliorer notre service"; +"share.data.text.description" = "Pour nous aider à garantir les performances de connexion de notre service, vous pouvez partager vos statistiques de connexion de manière anonyme avec nous. Ces rapports ne contiennent aucune information personnellement identifiable."; +"share.data.text.footer" = "Vous pouvez toujours contrôler cela à partir de vos paramètres."; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/fr.lproj/Welcome.strings b/Resources/Resources/iOS/fr.lproj/Welcome.strings new file mode 100644 index 000000000..623c17c3a --- /dev/null +++ b/Resources/Resources/iOS/fr.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Connectez-vous à votre compte"; +"login.username.placeholder" = "Nom d'utilisateur (p1234567)"; +"login.password.placeholder" = "Mot de passe"; +"login.submit" = "CONNEXION"; +"login.restore.button" = "Vous n'avez pas reçu les détails de votre compte ?"; +"login.error.title" = "Connexion"; +"login.error.validation" = "Vous devez saisir un nom d'utilisateur et un mot de passe."; +"login.error.unauthorized" = "Votre nom d'utilisateur ou mot de passe est incorrect."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Connectez-vous à l'aide du reçu d'achat"; +"login.magic.link.title" = "Connectez-vous à l'aide du lien e-mail magique"; +"login.magic.link.response" = "Veuillez vérifier vos e-mails pour trouver un lien de connexion."; +"login.magic.link.send" = "Envoyer un lien"; +"login.magic.link.invalid.email" = "E-mail invalide. Veuillez réessayer."; + +"purchase.title" = "Sélectionnez un forfait VPN"; +"purchase.subtitle" = "Garantie satisfait ou remboursé sur 30 jours"; +"purchase.email.placeholder" = "Adresse e-mail"; +"purchase.continue" = "Continuer"; +"purchase.login.footer" = "Vous avez déjà un compte ?"; +"purchase.login.button" = "Connectez-vous"; +"purchase.error.title" = "Acheter"; +"purchase.error.validation" = "Vous devez entrer une adresse e-mail."; +"purchase.error.connectivity.title" = "Échec de la connexion"; +"purchase.error.connectivity.description" = "Nous n'arrivons pas à joindre Private Internet Access. Cela peut être dû à une connexion Internet de faible qualité ou parce que notre service est bloqué dans votre pays."; +"purchase.confirm.form.email" = "Saisissez votre adresse e-mail"; +"purchase.confirm.plan" = "Vous achetez le forfait %@"; +"purchase.email.why" = "Nous avons besoin de votre e-mail pour envoyer votre nom d'utilisateur et votre mot de passe."; +"purchase.submit" = "Envoyer"; +"purchase.or" = "ou"; + +"upgrade.header" = "Bienvenue !"; +"upgrade.title" = "Afin d'utiliser Private Internet Access, vous devrez renouveler votre abonnement."; +"upgrade.renew.now" = "Renouveler maintenant"; + + + +"redeem.title" = "Échanger carte cadeau"; +"redeem.subtitle" = "Veuillez saisir ci-dessous votre adresse e-mail et le code PIN à %lu chiffres de votre carte cadeau ou carte d'essai."; +"redeem.email.placeholder" = "Adresse e-mail"; +"redeem.submit" = "ENVOYER"; +"redeem.error.title" = "Échanger"; +"redeem.error.code" = "Le code doit contenir %lu chiffres numériques."; +"redeem.error.allfields" = "Saisissez votre e-mail et le code PIN de votre carte."; +"redeem.accessibility.back" = "Retour"; +"redeem.giftcard.placeholder" = "Code PIN de la carte"; + +"plan.monthly.title" = "Mensuellement"; +"plan.yearly.title" = "Annuellement"; +"plan.yearly.detail_format" = "%@%@ par an"; +"plan.price_format" = "%@/mois"; +"plan.best_value" = "Économique"; +"plan.accessibility.per_month" = "par mois"; + +"restore.title" = "Restaurer l'achat non crédité"; +"restore.subtitle" = "Si vous avez acheté un forfait via cette application et n'avez pas reçu vos identifiants, il est possible de les renvoyer à partir d'ici. Cette action ne vous sera pas facturée."; +"restore.email.placeholder" = "Adresse e-mail"; +"restore.submit" = "CONFIRMER"; + +"iap.error.message.unavailable" = "Les serveurs Apple ne sont pas disponibles actuellement. Veuillez réessayer plus tard."; +"iap.error.title" = "Erreur"; + +"agreement.trials.title" = "Termes et conditions des essais gratuits"; +"agreement.trials.message" = "Le paiement sera débité de votre compte Apple ID au moment de la confirmation de l'achat. L'abonnement se renouvelle automatiquement à moins qu'il ne soit annulé au moins 24 heures avant la fin de la période en cours. Votre compte sera débité du renouvellement dans les 24 heures précédant la fin de la période actuelle. Vous pouvez gérer et annuler vos abonnements en accédant aux paramètres du compte sur l'App Store après l'achat.\n\nCertains abonnements payants peuvent offrir un essai gratuit avant de débiter votre méthode de paiement. Si vous décidez de vous désabonner d'un abonnement payant avant que nous commencions à débiter votre méthode de paiement, annulez l'abonnement au moins 24 heures avant la fin de l'essai.\n\nLes essais gratuits ne sont disponibles que pour les nouveaux utilisateurs et sont à notre entière discrétion et si vous tentez de vous inscrire pour un autre essai gratuit, vous serez immédiatement débité des frais d'abonnement standards.\n\nNous nous réservons le droit de révoquer votre essai gratuit à tout moment.\n\nToute partie non utilisée de votre période d'essai gratuit sera abandonnée au moment de l'achat d'un abonnement.\n\nL'inscription constitue l'acceptation de ces termes et conditions."; +"agreement.message" = "Après l'essai gratuit de 7 jour, cet abonnement est renouvelé automatiquement pour %@, sauf s'il est annulé au moins 24 heures avant la fin de la période d'essai. Votre compte de l'identifiant Apple sera facturé pour le renouvellement 24 heures avant la fin de la période d'essai. Vous pouvez gérer et annuler vos abonnements en accédant aux paramètres de votre compte de l'App Store après l'achat. L'offre de l'essai de 7 jours est limité à une seule offre d'essai de 7 jours par utilisateur. Toute partie non utilisée d'une période d'essai (le cas échéant) sera abandonnée lorsque l'utilisateur achète une abonnement. Tous les prix comprennent les taxes locales applicables.\n\nL'abonnement signifie que vous acceptez les $1 et la $2."; +"agreement.trials.yearly.plan" = "an"; +"agreement.trials.monthly.plan" = "mois"; + +"agreement.message.tos" = "Conditions d'utilisation"; +"agreement.message.privacy" = "Politique de confidentialité"; + +"getstarted.buttons.buyaccount" = "Acheter un compte"; + +"gdpr.collect.data.title" = "Informations personnelles que nous collectons"; +"gdpr.collect.data.description" = "Adresse e-mail dans le but de gérer le compte et de protéger des abus."; +"gdpr.usage.data.title" = "Utilisation des informations personnelles que nous collectons"; +"gdpr.usage.data.description" = "L'adresse e-mail est utilisée pour envoyer les informations d'abonnement, les confirmation de paiement, la correspondance avec le client, et les offres promotionnelles de Private Internet Access uniquement."; +"gdpr.accept.button.title" = "Accepter et continuer"; + +"update.account.email.error" = "Échec de la modification de l'e-mail du compte"; diff --git a/Resources/Resources/iOS/it.lproj/Signup.strings b/Resources/Resources/iOS/it.lproj/Signup.strings new file mode 100644 index 000000000..b60ca1b4e --- /dev/null +++ b/Resources/Resources/iOS/it.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Conferma registrazione"; +"in_progress.message" = "Conferma dell'acquisto col sistema in corso. Potrebbe impiegare qualche secondo. Attendi."; +"in_progress.redeem.message" = "Conferma del PIN della tua carta col sistema in corso. Potrebbe impiegare qualche secondo. Attendi."; + +"success.title" = "Acquisto completato"; +"success.message_format" = "Grazie per la registrazione. Ti abbiamo inviato nome utente e password del tuo account all'indirizzo e-mail %@"; +"success.redeem.title" = "Carta riscossa"; +"success.redeem.message" = "Riceverai un'email a breve con nome utente e password.\n\nI tuoi dati d'accesso"; +"success.username.caption" = "Nome utente"; +"success.password.caption" = "Password"; +"success.submit" = "Inizia"; + +"failure.vc_title" = "Registrazione non riuscita"; +"failure.title" = "Errore di creazione account"; +"failure.message" = "Impossibile creare un account in questo momento. Riprova più tardi. \n\nRiaprendo l'app si riproverà a creare un account."; +"failure.purchase.sandbox.message" = "L'abbonamento del sandbox selezionato on è disponibile in produzione."; +"failure.redeem.invalid.title" = "PIN della carta non valido"; +"failure.redeem.invalid.message" = "Hai inserito un PIN della carta non valido. Riprova."; +"failure.redeem.claimed.title" = "Carta già riscattata"; +"failure.redeem.claimed.message" = "Questa carta è già stata riscattata da un altro account. Prova a inserire un PIN diverso."; +"failure.submit" = "INDIETRO"; + +"unreachable.vc_title" = "Errore"; +"unreachable.title" = "Ops!"; +"unreachable.message" = "Nessuna connessione Internet trovata. Verifica la connessione Internet e premi Riprova di seguito.\n\nPuoi tornare all'app più tardi per terminare il processo."; +"unreachable.submit" = "RIPROVA"; + +"purchase.uncredited.alert.message" = "Hai transazioni non accreditate. Vuoi recuperare i dati del tuo account?"; +"purchase.uncredited.alert.button.cancel" = "Annulla"; +"purchase.uncredited.alert.button.recover" = "Recupera account"; + +"purchase.trials.intro" = "Inizia la tua prova gratuita da 7 giorni"; +"purchase.trials.price.after" = "Poi a %@"; +"purchase.trials.money.back" = "Garanzia di rimborso entro 30 giorni"; +"purchase.trials.1year.protection" = "1 anno di privacy e protezione d'indentità"; +"purchase.trials.anonymous" = "Sfoglia anonimamente e nascondi il tuo IP."; +"purchase.trials.devices" = "Supporta 10 dispositivi alla volta"; +"purchase.trials.devices.description" = "Proteggi un massimo di 10 dispositivi alla volta."; +"purchase.trials.region" = "Connettiti facilmente a qualsiasi regione"; +"purchase.trials.servers" = "Oltre 3300 server in 32 Paesi"; +"purchase.trials.start" = "Inizia abbonamento"; +"purchase.trials.all.plans" = "Vedi tutti i piani disponibili"; + +"purchase.subscribe.now" = "Iscriviti ora"; + +// WALKTHROUGH + +"walkthrough.action.next" = "AVANTI"; +"walkthrough.action.done" = "FATTO"; +"walkthrough.action.skip" = "SALTA"; + +"walkthrough.page.1.title" = "Supporta 10 dispositivi alla volta"; +"walkthrough.page.1.description" = "Proteggi te stesso su un massimo di 10 dispositivi alla volta."; +"walkthrough.page.2.title" = "Connettiti facilmente a qualsiasi regione"; +"walkthrough.page.2.description" = "Con server in tutto il mondo, sei sempre protetto."; +"walkthrough.page.3.title" = "Proteggiti dalle pubblicità"; +"walkthrough.page.3.description" = "Abilitando il nostro Blocco dei contenuti non visualizzerai la pubblicità mentre navighi con Safari."; + +"share.data.buttons.accept" = "Accetta"; +"share.data.buttons.noThanks" = "No, grazie"; +"share.data.buttons.readMore" = "Leggi di più"; +"share.data.text.title" = "Aiutaci a migliorare il tuo servizio"; +"share.data.text.description" = "Per aiutarci a garantire le prestazioni di connessione del nostro servizio, puoi condividere in modo anonimo le tue statistiche di connessione con noi. Questi rapporti non contengono informazioni d'identificazione personale."; +"share.data.text.footer" = "Puoi sempre controllare questa funzione dalle tue impostazioni"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/it.lproj/Welcome.strings b/Resources/Resources/iOS/it.lproj/Welcome.strings new file mode 100644 index 000000000..197265683 --- /dev/null +++ b/Resources/Resources/iOS/it.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Accedi al tuo account"; +"login.username.placeholder" = "Nome utente (p1234567)"; +"login.password.placeholder" = "Password"; +"login.submit" = "ACCEDI"; +"login.restore.button" = "Non hai ancora ricevuto i dettagli dell'account?"; +"login.error.title" = "Accedi"; +"login.error.validation" = "Devi inserire un nome utente e una password."; +"login.error.unauthorized" = "Nome utente o password non valida"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Accedi mediante ricevuta d'acquisto"; +"login.magic.link.title" = "Accedi tramite il link magico della mail"; +"login.magic.link.response" = "Controlla la tua mail per ottenere il link d'accesso."; +"login.magic.link.send" = "Invia link"; +"login.magic.link.invalid.email" = "Indirizzo email non valido. Riprova."; + +"purchase.title" = "Seleziona un piano VPN"; +"purchase.subtitle" = "Garanzia di rimborso entro 30 giorni"; +"purchase.email.placeholder" = "Indirizzo email"; +"purchase.continue" = "Continua"; +"purchase.login.footer" = "Possiedi già un account?"; +"purchase.login.button" = "Accedi"; +"purchase.error.title" = "Acquista"; +"purchase.error.validation" = "Devi indicare un indirizzo e-mail."; +"purchase.error.connectivity.title" = "Errore di connessione"; +"purchase.error.connectivity.description" = "Non siamo in grado di stabilire l'accesso a una rete Internet privata. Ciò potrebbe essere dovuto a una scarsa qualità della rete o a un blocco dei nostri servizi nel tuo paese."; +"purchase.confirm.form.email" = "Inserisci il tuo indirizzo email"; +"purchase.confirm.plan" = "Stai acquistando il piano %@"; +"purchase.email.why" = "Per inviarti nome utente e password, abbiamo bisogno del tuo indirizzo email."; +"purchase.submit" = "Invia"; +"purchase.or" = "o"; + +"upgrade.header" = "Bentornato!"; +"upgrade.title" = "Per usare Private Internet Access, devi rinnovare l'abbonamento."; +"upgrade.renew.now" = "Rinnova adesso"; + + + +"redeem.title" = "Riscatta la carta regalo"; +"redeem.subtitle" = "Digita qui sotto il tuo indirizzo email e le %lu cifre del PIN della carta regalo o carta di prova."; +"redeem.email.placeholder" = "Indirizzo email"; +"redeem.submit" = "INVIA"; +"redeem.error.title" = "Riscatta"; +"redeem.error.code" = "Il codice dev'essere di %lu cifre."; +"redeem.error.allfields" = "Digita il tuo indirizzo email e PIN della carta."; +"redeem.accessibility.back" = "Indietro"; +"redeem.giftcard.placeholder" = "PIN carta regalo"; + +"plan.monthly.title" = "Mensile"; +"plan.yearly.title" = "Annuale"; +"plan.yearly.detail_format" = "%@%@ all'anno"; +"plan.price_format" = "%@ al mese"; +"plan.best_value" = "Valore migliore"; +"plan.accessibility.per_month" = "al mese"; + +"restore.title" = "Ripristina acquisto non accreditato"; +"restore.subtitle" = "Se hai acquistato un piano mediante questa app ma non hai ricevuto le tue credenziali, puoi inviarle nuovamente da qui.\nNon verrà effettuato alcun addebito durante la procedura."; +"restore.email.placeholder" = "Indirizzo email"; +"restore.submit" = "CONFERMA"; + +"iap.error.message.unavailable" = "Server Apple attualmente non disponibili. Riprova più tardi."; +"iap.error.title" = "Errore"; + +"agreement.trials.title" = "Termini e condizioni della prova gratuita"; +"agreement.trials.message" = "Il pagamento verrà addebitato sul tuo account ID Apple alla conferma dell'acquisto. L'abbonamento si rinnova automaticamente a meno che non venga annullato entro 24 ore dalla fine del periodo attuale. Il tuo account verrà addebitato per il rinnovo entro 24 ore dalla fine del periodo attuale. Puoi gestire e cancellare i tuoi abbonamenti dalle impostazioni dell'account sull'App Store dopo l'acquisto.\n\nAlcuni abbonamenti a pagamento possono offrire una prova gratuita prima di addebitare il metodo di pagamento. Se decidi di annullare l'iscrizione a un abbonamento a pagamento prima dell'addebito, dovrai annullarla entro 24 ore dalla scadenza della prova gratuita.\n\nLe prove gratuite sono disponibili solo per i nuovi utenti e sono a nostra esclusiva discrezione. In caso di registrazione per ottenere una prova gratuita aggiuntiva, l'addebito dell'importo standard dell'abbonamento verrà effettuato immediatamente.\n\nCi riserviamo il diritto di revocare la prova gratuita in qualsiasi momento.\n\nQualsiasi parte inutilizzata del periodo di prova gratuito andrà persa al momento dell'acquisto di un abbonamento.\n\nLa registrazione implica l'accettazione dei presenti termini e condizioni."; +"agreement.message" = "Dopo 7 giorni di prova gratuita, l'abbonamento si rinnova automaticamente per % @ a meno che non venga annullato entro 24 ore dalla fine del periodo di prova. Il tuo account ID Apple verrà addebitato per il rinnovo entro 24 ore dalla fine del periodo di prova. Puoi gestire e cancellare i tuoi abbonamenti andando sulle impostazioni del tuo account App Store dopo l'acquisto. L'offerta di prova di 7 giorni è limitata a un'unica offerta da 7 giorni per utente. Ogni parte inutilizzata di un periodo di prova gratuito, se offerto, andrà perduta quando l'utente acquista un abbonamento. Tutti i prezzi includono le tasse locali applicabili.\n\nLa registrazione implica l'accettazione di $1 e $2."; +"agreement.trials.yearly.plan" = "anno"; +"agreement.trials.monthly.plan" = "mese"; + +"agreement.message.tos" = "Termini di servizio"; +"agreement.message.privacy" = "Informativa sulla Privacy"; + +"getstarted.buttons.buyaccount" = "Acquista account"; + +"gdpr.collect.data.title" = "Dati personali da noi raccolti"; +"gdpr.collect.data.description" = "Indirizzo email ai fini di gestione dell'account e della protezione dall'uso improprio."; +"gdpr.usage.data.title" = "Usi delle informazioni personali da noi richieste"; +"gdpr.usage.data.description" = "L'indirizzo email viene utilizzato solo per inviare informazioni sull'abbonamento, conferme di pagamento, corrispondenza col cliente e offerte promozionali di Private Internet Access."; +"gdpr.accept.button.title" = "Accetta e continua"; + +"update.account.email.error" = "Modifica email account non riuscita"; diff --git a/Resources/Resources/iOS/ja.lproj/Signup.strings b/Resources/Resources/iOS/ja.lproj/Signup.strings new file mode 100644 index 000000000..886508935 --- /dev/null +++ b/Resources/Resources/iOS/ja.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "サインアップを確定"; +"in_progress.message" = "システムがご購入を確定しています。しばらく時間がかかることがありますので、そのままお待ちください。"; +"in_progress.redeem.message" = "システムがご購入を確定しています。しばらく時間がかかることがありますので、そのままお待ちください。"; + +"success.title" = "購入完了"; +"success.message_format" = "サインアップありがとうございます。アカウントのユーザー名とパスワードをお客様のメールアドレス(%@)に送信いたしました。"; +"success.redeem.title" = "カードの引き換えが完了しました"; +"success.redeem.message" = "ユーザーネームとパスワードを記載したメールがまもなく届きます。\n\nお客様のログイン詳細"; +"success.username.caption" = "ユーザー名"; +"success.password.caption" = "パスワード"; +"success.submit" = "始める"; + +"failure.vc_title" = "サインアップできませんでした"; +"failure.title" = "アカウントの作成に失敗しました"; +"failure.message" = "ただ今アカウントを作成できません。後ほどもう一度お試しください。\n\nアプリを再起動すると、アカウント作成が再試行されます。"; +"failure.purchase.sandbox.message" = "選択されたサンドボックスのサブスクリプションは生産中のため利用できません。"; +"failure.redeem.invalid.title" = "無効なカードPIN"; +"failure.redeem.invalid.message" = "無効なカードPINを入力したようです。もう一度お試しください。"; +"failure.redeem.claimed.title" = "すでに獲得されたカードです"; +"failure.redeem.claimed.message" = "このカードは、すでに別のアカウントが獲得したようです。別のPINを入力してください。"; +"failure.submit" = "戻る"; + +"unreachable.vc_title" = "エラー"; +"unreachable.title" = "おっと!"; +"unreachable.message" = "インターネット接続が見つかりません。インターネットに接続していることを確認してから下の再試行をタップしてください。\n\n後ほどアプリでこのプロセスを完了することができます。"; +"unreachable.submit" = "再試行"; + +"purchase.uncredited.alert.message" = "反映されていない取引があります。アカウントの詳細を回復しますか?"; +"purchase.uncredited.alert.button.cancel" = "キャンセル"; +"purchase.uncredited.alert.button.recover" = "アカウントを回復"; + +"purchase.trials.intro" = "7日間無料トライアルを開始"; +"purchase.trials.price.after" = "以後%@"; +"purchase.trials.money.back" = "30日間返金保証"; +"purchase.trials.1year.protection" = "1年間のプライバシーおよび個人情報の保護"; +"purchase.trials.anonymous" = "ウェブの匿名利用でIPを非表示にします。"; +"purchase.trials.devices" = "一度に10台の端末をサポート"; +"purchase.trials.devices.description" = "一度に最大10台の端末を保護して自分を守ることができます。"; +"purchase.trials.region" = "すべての地域に簡単に接続"; +"purchase.trials.servers" = "32か国の3300以上のサーバー"; +"purchase.trials.start" = "サブスクリプションを開始"; +"purchase.trials.all.plans" = "利用可能なプランをすべて見る"; + +"purchase.subscribe.now" = "今すぐ定期購読を購入"; + +// WALKTHROUGH + +"walkthrough.action.next" = "次へ"; +"walkthrough.action.done" = "完了"; +"walkthrough.action.skip" = "スキップ"; + +"walkthrough.page.1.title" = "一度に10台の端末をサポート"; +"walkthrough.page.1.description" = "一度に最大10台の端末を保護して自分を守ることができます。"; +"walkthrough.page.2.title" = "あらゆる地域に簡単に接続"; +"walkthrough.page.2.description" = "世界中にサーバがあるので、常に保護された状態でいることができます。"; +"walkthrough.page.3.title" = "広告から自分を守りましょう"; +"walkthrough.page.3.description" = "コンテンツブロッカーを有効にすると、Safariで広告表示をブロックできます。"; + +"share.data.buttons.accept" = "同意する"; +"share.data.buttons.noThanks" = "いいえ、結構です"; +"share.data.buttons.readMore" = "もっと読む"; +"share.data.text.title" = "弊社のサービス改善にご協力ください"; +"share.data.text.description" = "弊社のサービスの接続パフォーマンス確保にご協力いただくには、接続データを匿名で弊社と共有してください。これらのレポートには、個人を特定できる情報は含まれません。"; +"share.data.text.footer" = "これは、設定からいつでもコントロール可能です"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/ja.lproj/Welcome.strings b/Resources/Resources/iOS/ja.lproj/Welcome.strings new file mode 100644 index 000000000..98aa77a8f --- /dev/null +++ b/Resources/Resources/iOS/ja.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "アカウントにサインイン"; +"login.username.placeholder" = "ユーザー名 (p1234567)"; +"login.password.placeholder" = "パスワード"; +"login.submit" = "ログイン"; +"login.restore.button" = "アカウント詳細を受信しませんでしたか?"; +"login.error.title" = "ログイン"; +"login.error.validation" = "ユーザー名とパスワードを入力してください。"; +"login.error.unauthorized" = "ユーザー名またはパスワードが間違っています。"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "購入領収書を使用してログイン"; +"login.magic.link.title" = "魔法のメールリンクを使用してログイン"; +"login.magic.link.response" = "ログインリンクについては、メールを確認してください。"; +"login.magic.link.send" = "リンクを送信"; +"login.magic.link.invalid.email" = "無効なメールアドレス。もう一度お試しください。"; + +"purchase.title" = "VPNプランを選択"; +"purchase.subtitle" = "30日間返金保証"; +"purchase.email.placeholder" = "メールアドレス"; +"purchase.continue" = "続行"; +"purchase.login.footer" = "既にアカウントをお持ちですか?"; +"purchase.login.button" = "サインイン"; +"purchase.error.title" = "購入"; +"purchase.error.validation" = "必ずメールアドレスを入力してください。"; +"purchase.error.connectivity.title" = "接続エラー"; +"purchase.error.connectivity.description" = "Private Internet Accessに接続できませんでした。インターネットの接続が不安定、もしくはお住まいの国で当社サービスがブロックされている可能性があります。"; +"purchase.confirm.form.email" = "メールアドレスを入力してください"; +"purchase.confirm.plan" = "お客様は%@プランを購入しようとしています"; +"purchase.email.why" = "ユーザー名とパスワードを送信するためのメールアドレスを入力してください。"; +"purchase.submit" = "送信"; +"purchase.or" = "または"; + +"upgrade.header" = "お帰りなさい!"; +"upgrade.title" = "Private Internet Accessのご利用を継続するには、サブスクリプションを更新する必要があります。"; +"upgrade.renew.now" = "今すぐ更新"; + + + +"redeem.title" = "ギフトカード引換え"; +"redeem.subtitle" = "メールアドレスと、以下のギフトカードまたはトライアルカードの%lu桁のPINを入力してください。"; +"redeem.email.placeholder" = "メールアドレス"; +"redeem.submit" = "送信"; +"redeem.error.title" = "引換え"; +"redeem.error.code" = "コードは%lu桁でなければなりません。"; +"redeem.error.allfields" = "メールアドレスとカードのPINを入力してください。"; +"redeem.accessibility.back" = "戻る"; +"redeem.giftcard.placeholder" = "ギフトカードのPIN"; + +"plan.monthly.title" = "月間"; +"plan.yearly.title" = "年間"; +"plan.yearly.detail_format" = "年間%@%@"; +"plan.price_format" = "%@/月"; +"plan.best_value" = "最もお得"; +"plan.accessibility.per_month" = "月々"; + +"restore.title" = "追加されていない更新を復元"; +"restore.subtitle" = "このアプリでプランを購入した後、認証情報を受け取っていない方は、こちらから認証情報を再度送信することができます。この処理の実行中、課金は発生しません。"; +"restore.email.placeholder" = "メールアドレス"; +"restore.submit" = "確定"; + +"iap.error.message.unavailable" = "Appleサーバーが現在ご利用いただけません。後でもう一度お試しください。"; +"iap.error.title" = "エラー"; + +"agreement.trials.title" = "無料トライアル利用規約"; +"agreement.trials.message" = "ご購入確定時にお使いのApple IDアカウント支払額が請求されます。サブスクリプションは現在の期間が終了する24時間前までにキャンセルされない限り自動的に更新されます。更新料は現在の期間終了前の24時間以内にお使いのアカウントに請求されます。サブスクリプションはご購入後にApp Storeのアカウント設定からいつでも管理およびキャンセルすることができます。\n\n一部の有料サブスクリプションでは、ご希望の支払方法による請求が実施される前に無料トライアルが提供されている場合があります。ご選択の支払方法による請求が実施される前に有料サブスクリプションの解約をする場合は、無料トライアルが終了する24時間前までにサブスクリプションをキャンセルしてください。\n\n無料トライアルをご利用いただけるのは新規ユーザーのみとなり、無料トライアルを使用する目的で新たに追加のアカウントをサインアップした場合、弊社の裁量によって、通常のサブスクリプション料金が即時に請求されます。\n\n弊社は無料トライアル期間をいつでも無効にする権利を保持します。\n\nサブスクリプションご購入後、未使用分の無料トライアル期間は無効となります。\n\nサインアップすることで、$1と$2に同意したことになります。"; +"agreement.message" = "トライアル期間終了の少なくとも24時間前にキャンセルされない限り、7日間の無料トライアル後、この定期購読は自動的に%@で更新されます。更新料は、トライアル期間終了前の24時間以内にご利用のApple IDアカウントに請求されます。定期購読は、定期購読購入後にApp Storeアカウント設定から管理およびキャンセルすることができます。7日間のトライアルオファーは、ユーザー1人あたり1回の7日間トライアルに限られています。無料トライアルを利用した場合、無料トライアル期間の未使用分は、ユーザーが定期購読を購入した時点で無効となります。すべての料金には、適用可能な場合現地の消費税が含まれます。\n\nサインアップすることにより、$1および$2に同意したことになります。"; +"agreement.trials.yearly.plan" = "年"; +"agreement.trials.monthly.plan" = "月"; + +"agreement.message.tos" = "利用規約"; +"agreement.message.privacy" = "プライバシーポリシー"; + +"getstarted.buttons.buyaccount" = "アカウントを購入する"; + +"gdpr.collect.data.title" = "弊社が収集する個人情報"; +"gdpr.collect.data.description" = "メールアドレスは、アカウント管理、および乱用からの保護を目的とします。"; +"gdpr.usage.data.title" = "弊社により収集される個人情報の使用"; +"gdpr.usage.data.description" = "メールアドレスはサブスクリプション情報、お支払確認、お客様とのやり取り、およびPrivate Internet Accessのプロモーションオファーを送信するためにのみ使用されます。"; +"gdpr.accept.button.title" = "同意して続行する"; + +"update.account.email.error" = "アカウントのメールを変更できませんでした"; diff --git a/Resources/Resources/iOS/ko.lproj/Signup.strings b/Resources/Resources/iOS/ko.lproj/Signup.strings new file mode 100644 index 000000000..cfd62453f --- /dev/null +++ b/Resources/Resources/iOS/ko.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "회원 가입 확인"; +"in_progress.message" = "저희 시스템에서 고객님의 구매를 확인하고 있습니다. 약간 시간이 소요될 수 있으므로 양해 부탁드립니다."; +"in_progress.redeem.message" = "저희 시스템에서 고객님의 카드 PIN을 확인하고 있습니다. 약간 시간이 소요될 수 있으므로 양해 부탁드립니다."; + +"success.title" = "구매 완료"; +"success.message_format" = "회원으로 가입해 주셔서 감사합니다. 계정 사용자명과 비밀번호를 귀하의 이메일 주소(%@)로 발송했습니다."; +"success.redeem.title" = "카드 사용 성공"; +"success.redeem.message" = "사용자 이름 및 비밀번호가 담긴 이메일을 곧 보내드리겠습니다.\n\n귀하의 로그인 정보"; +"success.username.caption" = "사용자 이름"; +"success.password.caption" = "비밀번호"; +"success.submit" = "시작하기"; + +"failure.vc_title" = "회원 가입 실패"; +"failure.title" = "계정 생성 실패"; +"failure.message" = "지금은 계정을 생성할 수 없습니다. 나중에 다시 시도해주십시오.\n\n 앱을 다시 열면 계정 생성을 다시 시도합니다."; +"failure.purchase.sandbox.message" = "선택하신 샌드박스 구독은 생산에 사용할 수 없습니다."; +"failure.redeem.invalid.title" = "유효하지 않은 카드 PIN"; +"failure.redeem.invalid.message" = "유효하지 않은 카드 PIN을 입력한 것 같습니다. 다시 시도하세요."; +"failure.redeem.claimed.title" = "이미 청구한 카드"; +"failure.redeem.claimed.message" = "이 카드는 이미 다른 계정에서 청구한 것 같습니다. 다른 PIN을 입력해 보세요."; +"failure.submit" = "뒤로"; + +"unreachable.vc_title" = "오류"; +"unreachable.title" = "앗!"; +"unreachable.message" = "인터넷에 연결되지 않았습니다. 인터넷에 연결되어 있는지 확인하신 후 아래에서 다시 시도를 누르십시오.\n\n나중에 앱에 다시 돌아와서 이 과정을 완료할 수 있습니다."; +"unreachable.submit" = "다시 시도"; + +"purchase.uncredited.alert.message" = "처리되지 않은 거래가 있습니다. 계정 정보를 복구하시겠습니까?"; +"purchase.uncredited.alert.button.cancel" = "취소"; +"purchase.uncredited.alert.button.recover" = "계정 복구"; + +"purchase.trials.intro" = "7일 무료 체험 시작"; +"purchase.trials.price.after" = "그 후 %@"; +"purchase.trials.money.back" = "30일 이내 환불 보장"; +"purchase.trials.1year.protection" = "1년간 프라이버시 및 신원 보호"; +"purchase.trials.anonymous" = "익명으로 검색하고 IP를 숨기세요."; +"purchase.trials.devices" = "동시에 10대의 장치 지원"; +"purchase.trials.devices.description" = "한 번에 최대 10대의 장치에서 보호를 받으세요."; +"purchase.trials.region" = "모든 지역에 쉽게 연결"; +"purchase.trials.servers" = "32개국 3300개 이상의 서버"; +"purchase.trials.start" = "구독 시작"; +"purchase.trials.all.plans" = "이용 가능한 모든 플랜 보기"; + +"purchase.subscribe.now" = "지금 구독"; + +// WALKTHROUGH + +"walkthrough.action.next" = "다음"; +"walkthrough.action.done" = "완료"; +"walkthrough.action.skip" = "건너뛰기"; + +"walkthrough.page.1.title" = "한 번의 10대의 장치 지원"; +"walkthrough.page.1.description" = "한 번에 최대 10대의 장치에서 보호를 받으세요."; +"walkthrough.page.2.title" = "모든 지역에 쉽게 연결"; +"walkthrough.page.2.description" = "전 세계에 있는 서버를 통해 언제나 보호를 받습니다."; +"walkthrough.page.3.title" = "광고로부터 보호"; +"walkthrough.page.3.description" = "Content Blocker를 활성화하면 Safari에서 광고가 표시되지 않습니다."; + +"share.data.buttons.accept" = "수락"; +"share.data.buttons.noThanks" = "아니요"; +"share.data.buttons.readMore" = "자세히 보기"; +"share.data.text.title" = "저희 서비스를 개선하도록 도와 주세요"; +"share.data.text.description" = "연결 상태를 저희와 익명으로 공유해 주시면 저희 서비스의 연결 성능을 개선하는 데 도움이 됩니다. 이 보고서에는 개인 식별 정보가 포함되지 않습니다."; +"share.data.text.footer" = "언제든지 설정에서 이 옵션을 관리할 수 있습니다."; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/ko.lproj/Welcome.strings b/Resources/Resources/iOS/ko.lproj/Welcome.strings new file mode 100644 index 000000000..2d29b5f83 --- /dev/null +++ b/Resources/Resources/iOS/ko.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "계정에 로그인"; +"login.username.placeholder" = "사용자 이름 (p1234567)"; +"login.password.placeholder" = "비밀번호"; +"login.submit" = "로그인"; +"login.restore.button" = "계정 정보를 받지 못하셨습니까?"; +"login.error.title" = "로그인"; +"login.error.validation" = "사용자 이름과 비밀번호를 입력하셔야 합니다."; +"login.error.unauthorized" = "사용자명 또는 비밀번호가 틀립니다."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "구매 영수증을 사용해 로그인"; +"login.magic.link.title" = "이메일 링크를 사용해 간편하게 로그인"; +"login.magic.link.response" = "로그인 링크가 담긴 이메일을 확인하세요."; +"login.magic.link.send" = "링크 보내기"; +"login.magic.link.invalid.email" = "이메일이 유효하지 않음. 다시 시도하세요."; + +"purchase.title" = "VPN 플랜 선택"; +"purchase.subtitle" = "30일 이내 환불 보장"; +"purchase.email.placeholder" = "이메일 주소"; +"purchase.continue" = "계속"; +"purchase.login.footer" = "이미 계정이 있으세요?"; +"purchase.login.button" = "로그인"; +"purchase.error.title" = "구매"; +"purchase.error.validation" = "이메일 주소를 입력하셔야 합니다."; +"purchase.error.connectivity.title" = "연결 실패"; +"purchase.error.connectivity.description" = "Private Internet Access에 접속할 수 없습니다. 인터넷 연결 상태가 좋지 않거나 귀하의 국가에서 당사의 서비스가 차단된 것 같습니다."; +"purchase.confirm.form.email" = "이메일 주소를 입력하세요"; +"purchase.confirm.plan" = "%@ 플랜을 구매합니다"; +"purchase.email.why" = "사용자 이름 및 비밀번호를 보내 드리면 고객님의 이메일 주소가 필요합니다."; +"purchase.submit" = "제출"; +"purchase.or" = "또는"; + +"upgrade.header" = "다시 오신 걸 환영합니다!"; +"upgrade.title" = "Private Internet Access를 사용하려면 구독을 갱신하셔야 합니다."; +"upgrade.renew.now" = "지금 갱신"; + + + +"redeem.title" = "기프트 카드 청구"; +"redeem.subtitle" = "기프트 카드 또는 체험 카드의 %lu자리 PIN과 이메일 주소를 입력하세요."; +"redeem.email.placeholder" = "이메일 주소"; +"redeem.submit" = "제출"; +"redeem.error.title" = "청구"; +"redeem.error.code" = "코드는 %lu자리 숫자여야 합니다."; +"redeem.error.allfields" = "이메일 및 카드 PIN을 입력하세요."; +"redeem.accessibility.back" = "뒤로"; +"redeem.giftcard.placeholder" = "기프트 카드 PIN"; + +"plan.monthly.title" = "월간"; +"plan.yearly.title" = "연간"; +"plan.yearly.detail_format" = "매년 %@%@"; +"plan.price_format" = "%@/월"; +"plan.best_value" = "최저가"; +"plan.accessibility.per_month" = "매월"; + +"restore.title" = "인정되지 않은 구매 항목 복원"; +"restore.subtitle" = "이 앱을 통해 요금 플랜을 구매하셨는데 자격 증명 정보를 받지 못하신 경우 이곳에서 다시 보내실 수 있습니다. 이 과정 중 요금이 부과되지 않습니다.\n"; +"restore.email.placeholder" = "이메일 주소"; +"restore.submit" = "확인"; + +"iap.error.message.unavailable" = "현재 Apple 서버를 이용할 수 없습니다. 나중에 다시 시도해주십시오."; +"iap.error.title" = "오류"; + +"agreement.trials.title" = "무료 체험 계약 조건"; +"agreement.trials.message" = "구매 확인 시 사용자의 Apple ID 계정으로 요금이 청구됩니다. 현재 기간이 종료하기 24시간 전에 취소하지 않으면 구독은 자동으로 갱신됩니다. 현재 기간이 종료하기 전 24시간 이내에 갱신 요금이 계정으로 청구됩니다. 구매 후 App Store의 계정 설정에서 구독을 관리하고 취소할 수 있습니다.\n\n일부 유료 구독은 사용자의 결제 수단으로 청구하기 전에 무료 체험을 제공할 수 있습니다. 결제 수단으로 청구가 시작되기 전에 유료 구독을 취소하려면, 무료 체험 기간이 종료하기 24시간 전에 구독을 취소하십시오.\n\n무료 체험은 신규 사용자만 이용할 수 있으며, 당사의 단독 재량으로 제공됩니다. 무료 체험을 추가로 이용하기 위해 가입한 경우 표준 구독 요금이 즉시 청구됩니다.\n\n당사는 언제든지 무료 체험을 철회할 권리를 보유합니다.\n\n구독 구매 시 무료 체험 기간의 미사용분은 소멸됩니다.\n\n가입 시 본 계약 조건에 동의하신 것으로 간주됩니다."; +"agreement.message" = "체험 기간이 종료하기 24시간 전에 구독을 취소하지 않으면, 7일 무료 체험 후 이 구독은 %@에 자동으로 갱신됩니다. 체험 기간이 종료하기 전 24시간 이내에 사용자의 Apple ID로 갱신 요금이 청구됩니다. 구매 후 App Store 계정으로 이동하여 구독을 관리하고 취소할 수 있습니다. 7일 체험 혜택은 사용자당 한 번으로 제한됩니다. 사용자가 구독을 구매할 경우 무료 체험 기간의 미사용분은 소멸됩니다. 모든 가격에는 현지에서 적용되는 판매세가 포함됩니다.\n\n가입 시 $1 및 $2에 동의하신 것으로 간주됩니다."; +"agreement.trials.yearly.plan" = "년"; +"agreement.trials.monthly.plan" = "개월"; + +"agreement.message.tos" = "서비스 약관"; +"agreement.message.privacy" = "개인정보 취급방침"; + +"getstarted.buttons.buyaccount" = "계정 구입"; + +"gdpr.collect.data.title" = "당사가 수집하는 개인 정보"; +"gdpr.collect.data.description" = "계정 관리 및 악용 방지를 위한 이메일 주소."; +"gdpr.usage.data.title" = "수집된 개인 정보의 사용"; +"gdpr.usage.data.description" = "이메일 주소는 구독 정보, 결제 확인, 고객 공지 사항 및 Private Internet Access 프로모션 정보를 보내는 데에만 사용됩니다."; +"gdpr.accept.button.title" = "동의 및 계속"; + +"update.account.email.error" = "계정 이메일을 수정하지 못했습니다"; diff --git a/Resources/Resources/iOS/nb.lproj/Signup.strings b/Resources/Resources/iOS/nb.lproj/Signup.strings new file mode 100644 index 000000000..300d513ed --- /dev/null +++ b/Resources/Resources/iOS/nb.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Bekrefter registrering"; +"in_progress.message" = "Vi bekrefter kjøpet i systemet vårt. Dette kan ta litt tid."; +"in_progress.redeem.message" = "Vi bekrefter kort-PIN-en din i systemet vårt. Det kan ta et øyeblikk, så vennligst vent."; + +"success.title" = "Kjøp fullført"; +"success.message_format" = "Takk for at du registrerte deg. Vi har sendt deg kontonavnet og passordet ditt til e-postadressen din %@"; +"success.redeem.title" = "Kortet har blitt innløst"; +"success.redeem.message" = "Du mottar en e-post med brukernavn og passord.\n\nPåloggingsinformasjonen din"; +"success.username.caption" = "Brukernavn"; +"success.password.caption" = "Passord"; +"success.submit" = "Komme i gang"; + +"failure.vc_title" = "Registrering mislyktes"; +"failure.title" = "Kunne ikke opprette kontoen"; +"failure.message" = "Vi kunne ikke opprette en konto nå. Prøv på nytt senere.\n\nNår du åpner appen igjen, vil den prøve å opprette kontoen på nytt."; +"failure.purchase.sandbox.message" = "Det valgte sandboksabonnementet er ikke tilgjengelig i produksjon."; +"failure.redeem.invalid.title" = "Ugyldig kort-PIN"; +"failure.redeem.invalid.message" = "Ser ut til at du brukte en ugyldig kort-PIN. Prøv igjen"; +"failure.redeem.claimed.title" = "Kortet er allerede brukt"; +"failure.redeem.claimed.message" = "Ser ut til at kortet allerede er brukt av en annen konto. Du kan prøve med en annen PIN."; +"failure.submit" = "GÅ TILBAKE"; + +"unreachable.vc_title" = "Feil"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Ingen internettilkobling. Bekreft at du er koblet til Internett og trykk på Prøv igjen nedenfor.\n\nDu kan komme tilbake til appen senere for å fullføre prosessen."; +"unreachable.submit" = "PRØV PÅ NYTT"; + +"purchase.uncredited.alert.message" = "Du har ikke krediterte transaksjoner. Vil du gjenopprette kontoinformasjonen din?"; +"purchase.uncredited.alert.button.cancel" = "Abryt"; +"purchase.uncredited.alert.button.recover" = "Gjenopprett konto"; + +"purchase.trials.intro" = "Start din gratis 7-dagers prøveperiode"; +"purchase.trials.price.after" = "Deretter %@"; +"purchase.trials.money.back" = "30 dagers pengene-tilbake-garanti"; +"purchase.trials.1year.protection" = "Et års personverns- og identitetsbeskyttelse"; +"purchase.trials.anonymous" = "Surf anonymt og skjul IP-adressen din."; +"purchase.trials.devices" = "Støtter ti enheter om gangen"; +"purchase.trials.devices.description" = "Beskytt deg på opptil ti enheter samtidig."; +"purchase.trials.region" = "Koble til hvilken som helst region på en enkel måte"; +"purchase.trials.servers" = "Over 3300 servere i 32 land"; +"purchase.trials.start" = "Start abonnementet"; +"purchase.trials.all.plans" = "Vis alle tilgjengelige abonnement"; + +"purchase.subscribe.now" = "Abonner nå"; + +// WALKTHROUGH + +"walkthrough.action.next" = "NESTE"; +"walkthrough.action.done" = "FERDIG"; +"walkthrough.action.skip" = "HOPP OVER"; + +"walkthrough.page.1.title" = "Støtter ti enheter samtidig"; +"walkthrough.page.1.description" = "Beskytt deg på opptil ti enheter samtidig."; +"walkthrough.page.2.title" = "Koble til hvilken som helst region på en enkel måte"; +"walkthrough.page.2.description" = "Med serverer rundt om i hele verden, er du alltid beskyttet."; +"walkthrough.page.3.title" = "Beskytt deg selv mot reklame"; +"walkthrough.page.3.description" = "Aktivering av innholdsblokkereren sikrer at reklame ikke blir vist når du bruker Safari."; + +"share.data.buttons.accept" = "Godta"; +"share.data.buttons.noThanks" = "Nei takk"; +"share.data.buttons.readMore" = "Les mer"; +"share.data.text.title" = "Hjelp oss med å forbedre tjenesten vår"; +"share.data.text.description" = "For å hjelpe oss med å sikre tjenestens tilkoblingsytelse, kan du anonymt dele tilkoblingsstatistikken din med oss. Disse rapportene inkluderer informasjon som ikke er personlig identifiserbar."; +"share.data.text.footer" = "Du kan kontrollere dette fra innstillingene dine"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/nb.lproj/Welcome.strings b/Resources/Resources/iOS/nb.lproj/Welcome.strings new file mode 100644 index 000000000..80faed974 --- /dev/null +++ b/Resources/Resources/iOS/nb.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Logg inn på kontoen din"; +"login.username.placeholder" = "Brukernavn (p1234567)"; +"login.password.placeholder" = "Passord"; +"login.submit" = "LOGG INN"; +"login.restore.button" = "Har du ikke fått kontodetaljene?"; +"login.error.title" = "Logg på"; +"login.error.validation" = "Du må oppgi et brukernavn og passord."; +"login.error.unauthorized" = "Brukernavnet eller passordet ditt er feil."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Logg på med kjøpsbevis"; +"login.magic.link.title" = "Pålogging med magisk e-postkobling"; +"login.magic.link.response" = "Sjekk e-posten din for å finne påloggingskoblingen."; +"login.magic.link.send" = "Send kobling"; +"login.magic.link.invalid.email" = "Ugyldig e-post. Prøv igjen."; + +"purchase.title" = "Velg et VPN-abonnement"; +"purchase.subtitle" = "30 dagers pengene-tilbake-garanti"; +"purchase.email.placeholder" = "E-postadresse"; +"purchase.continue" = "Fortsett"; +"purchase.login.footer" = "Har du allerede en konto?"; +"purchase.login.button" = "Logg inn"; +"purchase.error.title" = "Kjøp"; +"purchase.error.validation" = "Du må angi en e-postadresse."; +"purchase.error.connectivity.title" = "Tilkoblingsfeil"; +"purchase.error.connectivity.description" = "Vi kunne ikke nå Private Internet Access. Dette kan skyldes dårlig Internett eller at tjenesten vår er blokkert i landet ditt."; +"purchase.confirm.form.email" = "Angi e-postadressen din"; +"purchase.confirm.plan" = "Du kjøper %@-abonnementet"; +"purchase.email.why" = "Vi trenger e-posten din for å sende deg brukernavnet og passordet ditt."; +"purchase.submit" = "Send inn"; +"purchase.or" = "eller"; + +"upgrade.header" = "Velkommen tilbake!"; +"upgrade.title" = "For å bruke en privat internettilgang, må du fornye abonnementet ditt."; +"upgrade.renew.now" = "Forny nå"; + + + +"redeem.title" = "Løs inn gavekort"; +"redeem.subtitle" = "Angi e-postadressen og den %lu-sifrede PIN-koden fra gavekortet eller prøvekortet nedenfor."; +"redeem.email.placeholder" = "E-postadresse"; +"redeem.submit" = "SEND"; +"redeem.error.title" = "Løs inn"; +"redeem.error.code" = "Koden må bestå av %lu siffer."; +"redeem.error.allfields" = "Angi e-postadressen din og kortet PIN-kode."; +"redeem.accessibility.back" = "Tilbake"; +"redeem.giftcard.placeholder" = "PIN-kode for gavekort"; + +"plan.monthly.title" = "Månedlig"; +"plan.yearly.title" = "Årlig"; +"plan.yearly.detail_format" = "%@%@ per år"; +"plan.price_format" = "%@/mnd"; +"plan.best_value" = "Mest for pengene"; +"plan.accessibility.per_month" = "per måned"; + +"restore.title" = "Gjenopprett ukreditert kjøp"; +"restore.subtitle" = "Hvis du har kjøpt en plan via appen og ikke har mottatt opplysningene dine, kan du sende dem på nytt herfra.\nDu belastes ikke under denne prosessen."; +"restore.email.placeholder" = "E-postadresse"; +"restore.submit" = "BEKREFT"; + +"iap.error.message.unavailable" = "Apple-serverne er for øyeblikket ikke tilgjengelige. Prøv igjen senere."; +"iap.error.title" = "Feil"; + +"agreement.trials.title" = "Vilkår og betingelser for gratis prøveperiode"; +"agreement.trials.message" = "Betalingen belastes Apple ID-kontoen din når du bekrefter kjøpet. Abonnementet fornyes automatisk med mindre det kanselleres minst 24 timer før slutten av den inneværende perioden. Kontoen blir belastet for fornyelse innen 24 timer før slutten av den inneværende perioden. Du kan administrere og kansellere abonnementene dine ved besøke kontoinnstillingene på App Store etter kjøpet.\n\nEnkelte betalte abonnementer kan tilby en gratis prøveperiode før det belaster betalingsmetoden din. Hvis du bestemmer deg for å avslutte et betalt abonnement før vi begynner å belaste betalingsmetoden din, må du kansellere abonnementet minst 24 timer før prøveperioden er slutt.\n\nGratis prøveperioder er kun tilgjengelig for nye brukere og utføres etter vårt eget skjønn. Hvis du forsøker å registrere deg med flere gratis prøveperioder, blir du øyeblikkelig belastet standard abonnementsavgift.\n\nVi forbeholder oss retten til å tilbakekalle din gratis prøveperiode når som helst.\n\nEventuell ubrukt del av en gratis prøveperiode går tapt ved kjøpe av et abonnement.\n\nVed å registrere deg samtykker du til disse vilkårene og betingelsene."; +"agreement.message" = "Etter den gratis 7-dagers prøveperioden fornyes abonnementet automatisk for %@, med mindre det kanselleres minst 24 timer før slutten av prøveperioden. Din Apple ID-konto belastes for fornyingen innen 24 timer før slutten av prøveperioden. Du kan administrere og avbryte abonnementene dine ved å gå til App Store-kontoinnstillingene etter kjøp. Det 7-dagers prøvetilbudet er begrenset til én 7-dagers prøveperiode per bruker. Eventuell ubrukt tid av den gratis prøveperioden går tapt hvis brukeren kjøper et abonnement. Alle priser inkluderer gjeldende lokale avgifter.\n\nVed å signere godtar du $1 og $2."; +"agreement.trials.yearly.plan" = "år"; +"agreement.trials.monthly.plan" = "måned"; + +"agreement.message.tos" = "Tjenestevilkår"; +"agreement.message.privacy" = "REntingslinjer om personvern"; + +"getstarted.buttons.buyaccount" = "Kjøpskonto"; + +"gdpr.collect.data.title" = "Personlig informasjon vi tar vare på"; +"gdpr.collect.data.description" = "E-postadresse for kontoadministrasjon og beskyttelse mot misbruk."; +"gdpr.usage.data.title" = "Bruk av personlig informasjon samlet inn av oss"; +"gdpr.usage.data.description" = "E-postadresse blir kun brukt for å sende ut informasjon om abonnementet, betalingsbekreftelser, kundekorrespondanse og tilbud om privat internettilgang."; +"gdpr.accept.button.title" = "Godta og fortsett"; + +"update.account.email.error" = "Kunne ikke endre kontoens e-post"; diff --git a/Resources/Resources/iOS/nl.lproj/Signup.strings b/Resources/Resources/iOS/nl.lproj/Signup.strings new file mode 100644 index 000000000..97c63fd93 --- /dev/null +++ b/Resources/Resources/iOS/nl.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Aanmelding bevestigen"; +"in_progress.message" = "We zijn uw aankoop aan het verifiëren in ons systeem. Dit kan eventjes duren, daarom vragen we u vriendelijk om geduld."; +"in_progress.redeem.message" = "We zijn uw pincode aan het verifiëren in ons systeem. Dit kan eventjes duren, daarom vragen we u vriendelijk om geduld."; + +"success.title" = "Aankoop voltooid"; +"success.message_format" = "Bedankt voor uw aanmelding. We hebben de gebruikersnaam en het wachtwoord voor uw account naar het volgende e-mailadres gestuurd: %@"; +"success.redeem.title" = "Kaart ingewisseld"; +"success.redeem.message" = "U ontvangt zo een e-mail met uw gebruikersnaam en wachtwoord."; +"success.username.caption" = "Gebruikersnaam"; +"success.password.caption" = "Wachtwoord"; +"success.submit" = "Aan de slag"; + +"failure.vc_title" = "Aanmelden mislukt"; +"failure.title" = "Account aanmaken mislukt"; +"failure.message" = "We kunnen op dit moment geen account maken. Probeer het later opnieuw. \n\nAls u de app opnieuw opent, wordt opnieuw geprobeerd een account te maken."; +"failure.purchase.sandbox.message" = "Het geselecteerde sandbox-abonnement is niet beschikbaar in productie."; +"failure.redeem.invalid.title" = "Ongeldige pincode"; +"failure.redeem.invalid.message" = "U heeft een ongeldige pincode ingevoerd. Probeer het opnieuw."; +"failure.redeem.claimed.title" = "Kaart al geclaimd"; +"failure.redeem.claimed.message" = "Deze kaart is door een ander account geclaimd. Probeer een andere pincode."; +"failure.submit" = "GA TERUG"; + +"unreachable.vc_title" = "Fout"; +"unreachable.title" = "Oeps!"; +"unreachable.message" = "Geen internetverbinding gevonden. Controleer uw internetverbinding en probeer het hieronder opnieuw.\n\nU kunt later naar de app terugkeren om het proces te voltooien."; +"unreachable.submit" = "OPNIEUW PROBEREN"; + +"purchase.uncredited.alert.message" = "U heeft niet-gecrediteerde transacties. Wilt u uw accountgegevens herstellen?"; +"purchase.uncredited.alert.button.cancel" = "Annuleren"; +"purchase.uncredited.alert.button.recover" = "Account herstellen"; + +"purchase.trials.intro" = "Start je gratis proefabonnement van 7 dagen"; +"purchase.trials.price.after" = "Daarna %@"; +"purchase.trials.money.back" = "30 dagen lang niet-goed-geld-teruggarantie"; +"purchase.trials.1year.protection" = "1 jaar aan privacy- en identiteitsbescherming"; +"purchase.trials.anonymous" = "Browse anoniem en verberg uw ip."; +"purchase.trials.devices" = "Ondersteun tien apparaten tegelijk"; +"purchase.trials.devices.description" = "Bescherm uzelf op tien apparaten tegelijk."; +"purchase.trials.region" = "Maak eenvoudig verbinding met elke regio"; +"purchase.trials.servers" = "Meer dan 3300 servers in 32 landen"; +"purchase.trials.start" = "Abonnement starten"; +"purchase.trials.all.plans" = "Bekijk de beschikbare abonnementen"; + +"purchase.subscribe.now" = "Nu abonneren"; + +// WALKTHROUGH + +"walkthrough.action.next" = "VOLGENDE"; +"walkthrough.action.done" = "KLAAR"; +"walkthrough.action.skip" = "OVERSLAAN"; + +"walkthrough.page.1.title" = "Ondersteun tien apparaten tegelijk"; +"walkthrough.page.1.description" = "Bescherm uzelf op tien apparaten tegelijk."; +"walkthrough.page.2.title" = "Maak eenvoudig verbinding met elke regio"; +"walkthrough.page.2.description" = "Met servers over de hele wereld wordt u altijd beschermd."; +"walkthrough.page.3.title" = "Bescherm uzelf tegen advertenties"; +"walkthrough.page.3.description" = "Als u onze Content Blocker inschakelt, krijgt u geen advertenties meer te zien in Safari."; + +"share.data.buttons.accept" = "Accepteren"; +"share.data.buttons.noThanks" = "Nee, bedankt"; +"share.data.buttons.readMore" = "Meer informatie"; +"share.data.text.title" = "Help ons onze service te verbeteren"; +"share.data.text.description" = "Om ons te helpen de verbindingsprestaties van onze dienst te verbeteren, kunt u uw verbindingsstatistieken anoniem met ons delen. Deze rapporten bevatten geen persoonsgegevens."; +"share.data.text.footer" = "U kunt dit via de Instellingen beheren"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/nl.lproj/Welcome.strings b/Resources/Resources/iOS/nl.lproj/Welcome.strings new file mode 100644 index 000000000..3c4007de5 --- /dev/null +++ b/Resources/Resources/iOS/nl.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Aanmelden bij uw account"; +"login.username.placeholder" = "Gebruikersnaam (p1234567)"; +"login.password.placeholder" = "Wachtwoord"; +"login.submit" = "INLOGGEN"; +"login.restore.button" = "Geen accountgegevens ontvangen?"; +"login.error.title" = "Inloggen"; +"login.error.validation" = "U moet een gebruikersnaam en wachtwoord invoeren."; +"login.error.unauthorized" = "Uw gebruikersnaam of wachtwoord is onjuist."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Inloggen met aankoopbewijs"; +"login.magic.link.title" = "Log in met de magische link in uw e-mail"; +"login.magic.link.response" = "Controleer uw e-mail voor een inloglink."; +"login.magic.link.send" = "Link verzenden"; +"login.magic.link.invalid.email" = "Ongeldige e-mail. Probeer het opnieuw."; + +"purchase.title" = "Selecteer een VPN-abonnement"; +"purchase.subtitle" = "30 dagen lang niet-goed-geld-teruggarantie"; +"purchase.email.placeholder" = "E-mailadres"; +"purchase.continue" = "Doorgaan"; +"purchase.login.footer" = "Heeft u al een account?"; +"purchase.login.button" = "Aanmelden"; +"purchase.error.title" = "Kopen"; +"purchase.error.validation" = "U moet een e-mailadres invoeren"; +"purchase.error.connectivity.title" = "Verbindingsfout"; +"purchase.error.connectivity.description" = "We kunnen Private Internet Access niet bereiken. Dit kan komen door een slechte internetverbinding of omdat onze dienst in uw land is geblokkeerd."; +"purchase.confirm.form.email" = "Voer uw e-mailadres in"; +"purchase.confirm.plan" = "U koop het %@-abonnement"; +"purchase.email.why" = "We hebben uw e-mailadres nodig om uw gebruikersnaam en wachtwoord te versturen."; +"purchase.submit" = "Versturen"; +"purchase.or" = "of"; + +"upgrade.header" = "Welkom terug!"; +"upgrade.title" = "U moet uw abonnement vernieuwen om Private Internet Access te kunnen gebruiken."; +"upgrade.renew.now" = "Nu vernieuwen"; + + + +"redeem.title" = "Cadeaubon inwisselen"; +"redeem.subtitle" = "Voer uw e-mailadres en de %lu-cijferige pincode van uw cadeaubon of proefperiodekaart hieronder in."; +"redeem.email.placeholder" = "E-mailadres"; +"redeem.submit" = "VERSTUREN"; +"redeem.error.title" = "Inwisselen"; +"redeem.error.code" = "Code moet uit %lu getallen bestaan."; +"redeem.error.allfields" = "Voer uw e-mailadres en pincode in."; +"redeem.accessibility.back" = "Terug"; +"redeem.giftcard.placeholder" = "Pincode cadeaubon"; + +"plan.monthly.title" = "Maandelijks"; +"plan.yearly.title" = "Jaarlijks"; +"plan.yearly.detail_format" = "%@%@ per jaar"; +"plan.price_format" = "%@/ma"; +"plan.best_value" = "Beste waarde"; +"plan.accessibility.per_month" = "per maand"; + +"restore.title" = "Aankoop herstellen"; +"restore.subtitle" = "Als u een abonnement via deze app heeft aangeschaft en u heeft uw gegevens niet ontvangen, dan kunt u ze hier opnieuw verzenden. Er worden geen kosten in rekening gebracht tijdens dit proces."; +"restore.email.placeholder" = "E-mailadres"; +"restore.submit" = "BEVESTIGEN"; + +"iap.error.message.unavailable" = "De Apple-servers zijn momenteel niet beschikbaar. Probeer het later opnieuw."; +"iap.error.title" = "Fout"; + +"agreement.trials.title" = "Algemene voorwaarden gratis proefabonnementen"; +"agreement.trials.message" = "De betaling wordt bij de bevestiging van uw aankoop via uw Apple ID-account in rekening gebracht. Het abonnement wordt automatisch verlengd, tenzij het ten minste 24 uur voor het einde van de huidige periode wordt geannuleerd. De verlenging van uw account wordt binnen 24 uur voor het einde van de huidige periode in rekening gebracht. U kunt uw abonnementen beheren en annuleren door na de aankoop naar uw accountinstellingen in de App Store te gaan.\n\nBepaalde betaalde abonnementen kunnen een gratis proefabonnement aanbieden voordat er kosten in rekening worden gebracht. Als u zich wilt afmelden voor een betaald abonnement voordat we kosten in rekening brengen, moet u het abonnement ten minste 24 uur voor het einde van de gratis proefperiode annuleren.\n\nGratis proefabonnementen zijn alleen beschikbaar voor nieuwe gebruikers. Als u zich aanmeldt voor een aanvullend gratis proefabonnement worden onmiddellijk de standaard abonnementskosten in rekening gebracht.\n\nWij behouden ons het recht voor om uw gratis proefabonnement te allen tijde in te trekken.\n\nEen eventueel ongebruikt deel van uw gratis proefperiode vervalt bij aankoop van een abonnement.\n\nAls u zich aanmeldt, gaat u akkoord met deze algemene voorwaarden."; +"agreement.message" = "Na de gratis proefperiode van 7 dagen wordt het abonnement automatisch verlengd voor %@, tenzij u het ten minste 24 uur voor het einde van de proefperiode annuleert. De kosten voor de verlenging worden binnen 24 uur voor het einde van de proefperiode via uw Apple ID-account in rekening gebracht. U kunt uw abonnementen beheren en annuleren door na de aankoop naar uw accountinstellingen in de App Store te gaan. De proefperiode van 7 dagen is beperkt tot één proefperiode van 7 dagen per gebruiker. Een eventueel ongebruikt deel van uw gratis proefperiode vervalt bij aankoop van een abonnement. Alle prijzen zijn inclusief lokale omzetbelasting, indien van toepassing.\n\nAls u zich aanmeldt, gaat u akkoord met de $1 en het $2."; +"agreement.trials.yearly.plan" = "jaar"; +"agreement.trials.monthly.plan" = "maand"; + +"agreement.message.tos" = "Servicevoorwaarden"; +"agreement.message.privacy" = "Privacybeleid"; + +"getstarted.buttons.buyaccount" = "Account kopen"; + +"gdpr.collect.data.title" = "Persoonlijke informatie die we verzamelen"; +"gdpr.collect.data.description" = "E-mailadres voor accountbeheer en bescherming tegen misbruik."; +"gdpr.usage.data.title" = "Gebruik van de persoonlijke informatie die we verzamelen"; +"gdpr.usage.data.description" = "E-mailadres wordt alleen gebruikt voor het verzenden van abonnementsinformatie, betalingsbevestigingen, correspondentie met klanten en promotionele aanbiedingen van Private Internet Access."; +"gdpr.accept.button.title" = "Akkoord en doorgaan"; + +"update.account.email.error" = "Kan accountmail niet aanpassen"; diff --git a/Resources/Resources/iOS/pl.lproj/Signup.strings b/Resources/Resources/iOS/pl.lproj/Signup.strings new file mode 100644 index 000000000..9922f65c3 --- /dev/null +++ b/Resources/Resources/iOS/pl.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Potwierdź rejestrację"; +"in_progress.message" = "Potwierdzamy zakup w naszym systemie. Poczekaj spokojnie, bo to może trochę potrwać."; +"in_progress.redeem.message" = "Potwierdzamy Twój PIN karty w naszym systemie, TO może chwilę potrwać, więc prosimy o cierpliwość."; + +"success.title" = "Zakup zakończony"; +"success.message_format" = "Dziękujemy za rejestrację. Przesłaliśmy Twoją nazwę użytkownika i hasło na Twój adres e-mail: %@"; +"success.redeem.title" = "Karta została wymieniona"; +"success.redeem.message" = "Wkrótce otrzymasz e-mail z nazwą użytkownika i hasłem.\n\nTwoje dane do logowania"; +"success.username.caption" = "Nazwa użytkownika"; +"success.password.caption" = "Hasło"; +"success.submit" = "Rozpocznij"; + +"failure.vc_title" = "Rejestracja nie powiodła się"; +"failure.title" = "Błąd tworzenia konta"; +"failure.message" = "Obecnie nie możemy utworzyć konta. Spróbuj ponownie później."; +"failure.purchase.sandbox.message" = "Wybrana subskrypcja na piaskownicę (środowisko testowe) nie jest dostępna w produkcji."; +"failure.redeem.invalid.title" = "Nieprawidłowy PIN karty"; +"failure.redeem.invalid.message" = "Wygląda na to, ze wpisałeś nieprawidłowy PIN karty. Spróbuj ponownie."; +"failure.redeem.claimed.title" = "Karta już użyta"; +"failure.redeem.claimed.message" = "Wygląda na to, że ta karta została użyta na innym koncie. Możesz spróbować wpisać inny PIN."; +"failure.submit" = "WSTECZ"; + +"unreachable.vc_title" = "Błąd"; +"unreachable.title" = "Ups!"; +"unreachable.message" = "Nie znaleziono połączenia z internetem. Potwierdź, że masz połączenie z internetem i naciśnij „Spróbuj ponownie” poniżej..\n\nMożesz wrócić do aplikacji później, aby dokończyć proces."; +"unreachable.submit" = "SPRÓBUJ PONOWNIE"; + +"purchase.uncredited.alert.message" = "Masz nieuznane transakcje. Chcesz odzyskać dane swojego konta?"; +"purchase.uncredited.alert.button.cancel" = "Anuluj"; +"purchase.uncredited.alert.button.recover" = "Odzyskaj konto"; + +"purchase.trials.intro" = "Zacznij 7-dniowy bezpłatny okres próbny"; +"purchase.trials.price.after" = "Potem %@"; +"purchase.trials.money.back" = "30-dniowa gwarancja zwrotu pieniędzy"; +"purchase.trials.1year.protection" = "1 rok ochrony prywatności i tożsamości"; +"purchase.trials.anonymous" = "Przeglądaj sieć anonimowa i ukryj swoje IP"; +"purchase.trials.devices" = "Obsługa 10 urządzeń jednocześnie"; +"purchase.trials.devices.description" = "Ochrona na maksymalnie 10 urządzeniach jednocześnie."; +"purchase.trials.region" = "Łatwo połączysz się z dowolnym regionem"; +"purchase.trials.servers" = "Ponad 3300 serwerów w 32 krajach"; +"purchase.trials.start" = "Rozpocznij subskrypcję"; +"purchase.trials.all.plans" = "Sprawdź wszystkie dostępne plany"; + +"purchase.subscribe.now" = "Subskrybuj teraz"; + +// WALKTHROUGH + +"walkthrough.action.next" = "DALEJ"; +"walkthrough.action.done" = "GOTOWE"; +"walkthrough.action.skip" = "POMIŃ"; + +"walkthrough.page.1.title" = "Obsługa 10 urządzeń jednocześnie"; +"walkthrough.page.1.description" = "Ochrona na maksymalnie 10 urządzeniach jednocześnie."; +"walkthrough.page.2.title" = "Łatwo połączysz się z dowolnym regionem"; +"walkthrough.page.2.description" = "Dzięki serwerom na całym świecie zawsze jesteś pod ochroną."; +"walkthrough.page.3.title" = "Unikaj reklam"; +"walkthrough.page.3.description" = "Włączenie naszej Blokady zawartości chroni Cię przed wyświetlaniem reklam w Safari."; + +"share.data.buttons.accept" = "Akceptuj"; +"share.data.buttons.noThanks" = "Nie, dziękuję"; +"share.data.buttons.readMore" = "Dowiedz się więcej"; +"share.data.text.title" = "Prosimy o pomoc w ulepszeniu naszych usług"; +"share.data.text.description" = "Aby pomóc nam zapewnić najlepszą wydajność naszych usług, możesz anonimowo udostępniać nam swoje statystyki połączeń. Raporty te nie zawierają żadnych informacji umożliwiających identyfikację osób."; +"share.data.text.footer" = "Zawsze możesz to kontrolować w swoich ustawieniach"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/pl.lproj/Welcome.strings b/Resources/Resources/iOS/pl.lproj/Welcome.strings new file mode 100644 index 000000000..1af0054e2 --- /dev/null +++ b/Resources/Resources/iOS/pl.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Zaloguj się na konto"; +"login.username.placeholder" = "Nazwa użytkownika (p1234567)"; +"login.password.placeholder" = "Hasło"; +"login.submit" = "ZALOGUJ"; +"login.restore.button" = "Nie dostałeś(-aś) Danych swojego konta?"; +"login.error.title" = "Zaloguj"; +"login.error.validation" = "Musisz podać nazwę użytkownika i hasło."; +"login.error.unauthorized" = "Twoja nazwa użytkownika i hasło są nieprawidłowe."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Zaloguj się, używając pokwitowania zakupu"; +"login.magic.link.title" = "Zaloguj się, używając sekretnego linku z e-maila"; +"login.magic.link.response" = "Link do logowania wysłaliśmy e-mailem,"; +"login.magic.link.send" = "Wyślij link"; +"login.magic.link.invalid.email" = "Nieprawidłowy e-mail. Spróbuj ponownie"; + +"purchase.title" = "Wybierz plan VPN"; +"purchase.subtitle" = "30-dniowej gwarancji zwrotu pieniędzy"; +"purchase.email.placeholder" = "Adres e-mail"; +"purchase.continue" = "Kontynuuj"; +"purchase.login.footer" = "Masz już konto?"; +"purchase.login.button" = "Zaloguj"; +"purchase.error.title" = "Zakup"; +"purchase.error.validation" = "Musisz podać adres e-mail."; +"purchase.error.connectivity.title" = "Błąd połączenia"; +"purchase.error.connectivity.description" = "Nie można połączyć z Private Internet Access. Może to być spowodowane słabym połączeniem z internetem lub nasza usługa może być zablokowana w Twoim kraju."; +"purchase.confirm.form.email" = "Podaj swój adres e-mail"; +"purchase.confirm.plan" = "Kupujesz abonament %@"; +"purchase.email.why" = "Twój e-mail jest nam potrzebny do przesłania Ci nazwy użytkownika i hasła,"; +"purchase.submit" = "Wyślij"; +"purchase.or" = "lub"; + +"upgrade.header" = "Witaj ponownie!"; +"upgrade.title" = "Aby korzystać z Private Internet Access, musisz odnowić swoją subskrypcję."; +"upgrade.renew.now" = "Odnów teraz"; + + + +"redeem.title" = "Wykorzystaj kartę podarunkową"; +"redeem.subtitle" = "Wpisz swój adres e-mail oraz %lu-cyfrowy PIN z karty podarunkowej lub karty próbnej poniżej."; +"redeem.email.placeholder" = "Adres e-mail"; +"redeem.submit" = "PRZEŚLIJ"; +"redeem.error.title" = "Wykorzystaj"; +"redeem.error.code" = "Kod musi składać się z %lu znaków numerycznych."; +"redeem.error.allfields" = "Podaj swój adres r-mail i PIN karty"; +"redeem.accessibility.back" = "Wstecz"; +"redeem.giftcard.placeholder" = "PIN karty upominkowej"; + +"plan.monthly.title" = "Miesięcznie"; +"plan.yearly.title" = "Rocznie"; +"plan.yearly.detail_format" = "%@%@ rocznie"; +"plan.price_format" = "%@/msc."; +"plan.best_value" = "Najlepsza wartość"; +"plan.accessibility.per_month" = "miesięcznie"; + +"restore.title" = "Przywróć pominięty zakup"; +"restore.subtitle" = "Jeśli kupił(a)ś abonament, korzystając z tej aplikacji, ale nie dostałe(a)ś danych logowania, możesz wysłać je ponownie stąd.\nOpłata nie zostanie za to pobrana za tę czynność"; +"restore.email.placeholder" = "Adres e-mail"; +"restore.submit" = "POTWIERDŹ"; + +"iap.error.message.unavailable" = "Serwery Apple'a są w tej chwili niedostępne. Spróbuj ponownie później."; +"iap.error.title" = "Błąd"; + +"agreement.trials.title" = "Regulamin korzystania z bezpłatnej wersji próbnej"; +"agreement.trials.message" = "Płatność zostanie pobrana z Twojego konta Apple ID z chwilą potwierdzenia zakupu. Subskrypcja odnawia się automatycznie, chyba że zostanie anulowana co najmniej 24 godziny przed końcem bieżącego okresu rozliczeniowego. Opłata za odnowienie subskrypcji zostanie pobrana w ciągu 24 godzin przed końcem bieżącego okresu. Możesz zarządzać subskrypcjami i je anulować, przechodząc do ustawień konta w App Store po dokonaniu zakupu.\n\nCzęść płatnych Subskrypcji może obejmować bezpłatną wersję próbną, z której możesz skorzystać przed naliczeniem opłaty. Jeśli postanowisz zrezygnować z płatnej subskrypcji przed rozpoczęciem naliczania opłat zgodnie z wybraną metodą płatności, anuluj subskrypcję co najmniej 24 godziny przed zakończeniem bezpłatnej wersji próbnej.\n\nBezpłatne wersje próbne są dostępne tylko dla nowych użytkowników i są przyznawane wyłącznie według naszego uznania, a w przypadku próby zarejestrowania w celu uzyskania dodatkowej bezpłatnej wersji próbnej, zostaniesz natychmiast obciążony standardową opłatą subskrypcyjną.\n\nRejestracja oznacza akceptację niniejszego regulaminu."; +"agreement.message" = "Po 7 dniach bezpłatnego okresu próbnego ta subskrypcja odnowi się automatycznie na %@, jeżeli nie zostanie anulowana co najmniej 24 godziny przed końcem okresu próbnego. Twoje konto Apple ID zostanie obciążone opłatą za odnowienie w ciągu 24 godzin przed końcem okresu próbnego. Możesz zarządzać swoimi subskrypcjami i je anulować, wchodząc po zakupie w ustawienia swojego konta w App Store Oferta 7-dniowego okresu próbnego jest ograniczona – każdemu użytkownikowi przysługuje jeden 7-dniowy okres próbny. Każda niewykorzystana część bezpłatnego okresu próbnego, jeśli zostanie zaoferowany, przepada wraz zakupem subskrypcji przez użytkownika. Wszystkie ceny zawierają obowiązujące lokalne podatki obrotowe.\n\nRejestracja oznacza akceptację artykułów. $1 i $2."; +"agreement.trials.yearly.plan" = "rok"; +"agreement.trials.monthly.plan" = "miesiąc"; + +"agreement.message.tos" = "Warunki użytkowania"; +"agreement.message.privacy" = "Zasady ochrony prywatności"; + +"getstarted.buttons.buyaccount" = "Zakup konto"; + +"gdpr.collect.data.title" = "Zbierane dane osobowe"; +"gdpr.collect.data.description" = "Adres e-mail do zarządzania kontem i ochrony przed nadużyciami."; +"gdpr.usage.data.title" = "Sposoby wykorzystania zbieranych przez nas danych osobowych"; +"gdpr.usage.data.description" = "Adres e-mail; używany go do wysyłania informacji o subskrypcji, potwierdzeń płatności, korespondencji z klientami i wysyłania ofert promocyjnych wyłącznie Private Internet Access"; +"gdpr.accept.button.title" = "Zaakceptuj i kontynuuj"; + +"update.account.email.error" = "Nie udało się zmienić adresu e-mail konta"; diff --git a/Resources/Resources/iOS/pt-BR.lproj/Signup.strings b/Resources/Resources/iOS/pt-BR.lproj/Signup.strings new file mode 100644 index 000000000..5bcf7cb9a --- /dev/null +++ b/Resources/Resources/iOS/pt-BR.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Confirme o registro"; +"in_progress.message" = "Confirmamos sua compra com o nosso sistema. Isso pode demorar um pouco. Por favor, aguarde."; +"in_progress.redeem.message" = "Estamos confirmando o PIN do seu cartão com o nosso sistema. Isso pode demorar um pouco. Por favor, aguarde."; + +"success.title" = "Compra Concluída"; +"success.message_format" = "Obrigado por se registrar conosco. Nós enviamos o nome de usuário e a senha da sua conta para o seu endereço de e-mail em %@"; +"success.redeem.title" = "Cartão resgatado com sucesso"; +"success.redeem.message" = "Você receberá um e-mail com seu nome de usuário e senha em breve.\n\nSeus dados de login"; +"success.username.caption" = "Nome de usuário"; +"success.password.caption" = "Senha"; +"success.submit" = "Comece Agora"; + +"failure.vc_title" = "Falha ao registrar"; +"failure.title" = "Falha ao Criar Conta"; +"failure.message" = "Não podemos criar uma conta neste momento. Tente novamente mais tarde.\n\nApós a reabertua do aplicativo, uma nova tentativa de criação de conta será realizada."; +"failure.purchase.sandbox.message" = "A assinatura da área restrita selecionada não está disponível em produção."; +"failure.redeem.invalid.title" = "PIN de cartão inválido"; +"failure.redeem.invalid.message" = "Parece que você inseriu um PIN de cartão inválido. Por favor, tente novamente."; +"failure.redeem.claimed.title" = "O cartão já foi resgatado"; +"failure.redeem.claimed.message" = "Parece que este cartão já foi resgatado por outra conta. Você pode tentar usar um PIN diferente."; +"failure.submit" = "VOLTAR"; + +"unreachable.vc_title" = "Erro"; +"unreachable.title" = "Ops!"; +"unreachable.message" = "Nenhuma conexão com a Internet encontrada. Confirme que você possui uma conexão com a Internet e pressione Tentar Novamente abaixo.\n\nVocê pode retornar ao aplicativo mais tarde para finalizar o processo."; +"unreachable.submit" = "TENTAR NOVAMENTE"; + +"purchase.uncredited.alert.message" = "Você tem transações não creditadas. Deseja recuperar os detalhes da sua conta?"; +"purchase.uncredited.alert.button.cancel" = "Cancelar"; +"purchase.uncredited.alert.button.recover" = "Recuperar conta"; + +"purchase.trials.intro" = "Comece sua avaliação gratuita de 7 dias"; +"purchase.trials.price.after" = "Em seguida, %@"; +"purchase.trials.money.back" = "Garantia do dinheiro de volta em até 30 dias"; +"purchase.trials.1year.protection" = "1 ano de proteção de privacidade e identidade"; +"purchase.trials.anonymous" = "Navegue anonimamente e oculte seu IP."; +"purchase.trials.devices" = "Suporte para 10 dispositivos ao mesmo tempo"; +"purchase.trials.devices.description" = "Proteja-se em até 10 dispositivos ao mesmo tempo."; +"purchase.trials.region" = "Conecte-se a qualquer região facilmente"; +"purchase.trials.servers" = "Mais de 3.300 servidores em 32 países"; +"purchase.trials.start" = "Iniciar assinatura"; +"purchase.trials.all.plans" = "Veja todos os planos disponíveis"; + +"purchase.subscribe.now" = "Assine agora"; + +// WALKTHROUGH + +"walkthrough.action.next" = "AVANÇAR"; +"walkthrough.action.done" = "CONCLUÍDO"; +"walkthrough.action.skip" = "PULAR"; + +"walkthrough.page.1.title" = "Suporte para 10 dispositivos ao mesmo tempo"; +"walkthrough.page.1.description" = "Proteja-se em até 10 dispositivos ao mesmo tempo."; +"walkthrough.page.2.title" = "Conecte-se a qualquer região facilmente"; +"walkthrough.page.2.description" = "Com servidores ao redor do mundo, você está sempre protegido."; +"walkthrough.page.3.title" = "Proteja-se contra propagandas"; +"walkthrough.page.3.description" = "A ativação do nosso Bloqueador de Conteúdo impede que anúncios sejam exibidos no Safari."; + +"share.data.buttons.accept" = "Aceitar"; +"share.data.buttons.noThanks" = "Não, obrigado"; +"share.data.buttons.readMore" = "Leia mais"; +"share.data.text.title" = "Ajude-nos a melhorar nosso serviço"; +"share.data.text.description" = "Para nos ajudar a garantir o desempenho da conexão de nosso serviço, você pode compartilhar anonimamente as estatísticas da sua conexão conosco. Esses relatórios não incluem nenhuma informação de identificação pessoal."; +"share.data.text.footer" = "Você sempre poderá controlar isso em suas configurações"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/pt-BR.lproj/Welcome.strings b/Resources/Resources/iOS/pt-BR.lproj/Welcome.strings new file mode 100644 index 000000000..7ed6d1e85 --- /dev/null +++ b/Resources/Resources/iOS/pt-BR.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Entre na sua conta"; +"login.username.placeholder" = "Nome de usuário (p1234567)"; +"login.password.placeholder" = "Senha"; +"login.submit" = "ENTRAR"; +"login.restore.button" = "Não recebeu detalhes da conta?"; +"login.error.title" = "Entrar"; +"login.error.validation" = "Você deve inserir um nome de usuário e senha."; +"login.error.unauthorized" = "Seu nome de usuário ou senha está incorreto."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Faça login usando o recibo de compra"; +"login.magic.link.title" = "Faça login usando o link mágico enviado por e-mail"; +"login.magic.link.response" = "Veja se você recebeu por e-mail um link para fazer login."; +"login.magic.link.send" = "Enviar link"; +"login.magic.link.invalid.email" = "E-mail inválido. Tente novamente."; + +"purchase.title" = "Selecione um plano de VPN"; +"purchase.subtitle" = "Garantia do dinheiro de volta em até 30 dias"; +"purchase.email.placeholder" = "Endereço de e-mail"; +"purchase.continue" = "Continuar"; +"purchase.login.footer" = "Já tem uma conta?"; +"purchase.login.button" = "Faça login"; +"purchase.error.title" = "Comprar"; +"purchase.error.validation" = "Você precisa inserir um endereço de e-mail."; +"purchase.error.connectivity.title" = "Falha na conexão"; +"purchase.error.connectivity.description" = "Não conseguimos acessar o Private Internet Access. Isso pode ser devido a uma conexão de internet fraca ou o nosso serviço está bloqueado em seu país."; +"purchase.confirm.form.email" = "Insira seu endereço de e-mail"; +"purchase.confirm.plan" = "Você está adquirindo o plano %@"; +"purchase.email.why" = "Precisamos do seu e-mail para enviarmos seu nome de usuário e senha."; +"purchase.submit" = "Enviar"; +"purchase.or" = "ou"; + +"upgrade.header" = "Seja bem-vindo(a)!"; +"upgrade.title" = "Para usar a Private Internet Access, você precisará renovar sua assinatura."; +"upgrade.renew.now" = "Renovar agora"; + + + +"redeem.title" = "Resgatar cartão-presente"; +"redeem.subtitle" = "Digite o seu endereço de e-mail e o PIN de %lu dígitos do seu cartão-presente ou cartão de teste abaixo."; +"redeem.email.placeholder" = "Endereço de e-mail"; +"redeem.submit" = "ENVIAR"; +"redeem.error.title" = "Resgatar"; +"redeem.error.code" = "O código precisa ter %lu dígitos numéricos."; +"redeem.error.allfields" = "Digite o seu e-mail e PIN do cartão."; +"redeem.accessibility.back" = "Voltar"; +"redeem.giftcard.placeholder" = "PIN do cartão-presente"; + +"plan.monthly.title" = "Mensal"; +"plan.yearly.title" = "Anual"; +"plan.yearly.detail_format" = "%@%@ por ano"; +"plan.price_format" = "%@/mês"; +"plan.best_value" = "Melhor valor"; +"plan.accessibility.per_month" = "por mês"; + +"restore.title" = "Restaurar compra não creditada"; +"restore.subtitle" = "Se você adquiriu um plano por este aplicativo e não recebeu as suas credenciais, você pode enviá-las novamente por aqui. Você não será cobrado durante esse processo."; +"restore.email.placeholder" = "Endereço de e-mail"; +"restore.submit" = "CONFIRMAR"; + +"iap.error.message.unavailable" = "Servidores da Apple indisponíveis no momento. Tente novamente mais tarde."; +"iap.error.title" = "Erro"; + +"agreement.trials.title" = "Termos e condições das avaliações gratuitas"; +"agreement.trials.message" = "O pagamento será cobrado na sua conta do ID Apple no ato da confirmação da compra. A assinatura será renovada automaticamente, a não ser que ela seja cancelada, pelo menos, 24 horas antes do fim do período atual. O valor da renovação será debitado na sua conta em até 24 horas antes do término do período da atual. Você pode gerenciar e cancelar suas assinaturas nos ajustes da conta na App Store após a compra.\n\nCertas assinaturas pagas podem oferecer uma avaliação gratuita antes da cobrança do pagamento. Se você decidir cancelar uma Assinatura Paga antes de começarmos a cobrar por ela, cancele-a, pelo menos, 24 horas antes do término da avaliação gratuita.\n\nAs avaliações gratuitas estão disponíveis apenas para novos usuários, e são a nosso critério. Se tentar se registrar para uma avaliação gratuita adicional, você será cobrado imediatamente com a Taxa de Assinatura padrão.\n\nReservamo-nos o direito de revogar sua avaliação gratuita a qualquer momento.\n\nQualquer parte não utilizada do período da sua avaliação gratuita será perdida após a compra de uma assinatura.\n\nO registro constitui da aceitação dos termos e condições."; +"agreement.message" = "Após os 7 dias da avaliação gratuita, a assinatura será renovada automaticamente por %@, a não ser que ela seja cancelada, pelo menos, 24 horas antes do término do período de avaliação. O valor da renovação será debitado da conta do seu ID Apple em até 24 horas antes do término do período de avaliação. Você pode gerenciar e cancelar suas assinaturas nos ajustes da conta da App Store após a compra. A oferta de avaliação de 7 dias é limitada a uma oferta de avaliação de 7 dias por usuário. Qualquer parte não utilizada do período de avaliação gratuita, se oferecida, será perdida após a aquisição de uma assinatura. Todos os preços incluem impostos de vendas locais aplicáveis.\n\nO registro constitui da aceitação dos $1 e da $2."; +"agreement.trials.yearly.plan" = "ano"; +"agreement.trials.monthly.plan" = "mês"; + +"agreement.message.tos" = "Termos de Serviço"; +"agreement.message.privacy" = "Política de Privacidade"; + +"getstarted.buttons.buyaccount" = "Comprar conta"; + +"gdpr.collect.data.title" = "Informações pessoais que coletamos"; +"gdpr.collect.data.description" = "Endereço de e-mail para gerenciamento de conta e proteção contra abuso."; +"gdpr.usage.data.title" = "Uso de informações pessoais coletadas por nós"; +"gdpr.usage.data.description" = "O endereço de e-mail é utilizado apenas para enviar informação de assinatura, confirmações de pagamento, correspondência com clientes e ofertas promocionais do Private Internet Access."; +"gdpr.accept.button.title" = "Concordar e continuar"; + +"update.account.email.error" = "Falha ao modificar o e-mail da conta"; diff --git a/Resources/Resources/iOS/ru.lproj/Signup.strings b/Resources/Resources/iOS/ru.lproj/Signup.strings new file mode 100644 index 000000000..9f032f794 --- /dev/null +++ b/Resources/Resources/iOS/ru.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "Подтверждение регистрации"; +"in_progress.message" = "Мы проверяем вашу покупку в системе. На это может понадобиться время, так что оставайтесь с нами."; +"in_progress.redeem.message" = "Мы подтверждаем ваш PIN-код в системе. Это займет какое-то время, подождите немного."; + +"success.title" = "Покупка завершена"; +"success.message_format" = "Спасибо за регистрацию. Мы отправили имя пользователя и пароль на адрес электронной почты %@"; +"success.redeem.title" = "Карта успешно использована"; +"success.redeem.message" = "Также вы получите эл. письмо с именем пользователя и паролем.\n\nВаши учетные данные"; +"success.username.caption" = "Имя пользователя"; +"success.password.caption" = "Пароль"; +"success.submit" = "Начать"; + +"failure.vc_title" = "Ошибка регистрации"; +"failure.title" = "Сбой создания учетной записи"; +"failure.message" = "Нам не удалось создать учетную запись. Повторите попытку позже.\nПри повторном открытии приложения создание учетной записи будет возобновлено."; +"failure.purchase.sandbox.message" = "Выбранная подписка на «песочницу» недоступна в производственной среде."; +"failure.redeem.invalid.title" = "Неверный PIN-код карты"; +"failure.redeem.invalid.message" = "Похоже, вы ввели неверный PIN-код карты. Попробуйте еще раз."; +"failure.redeem.claimed.title" = "Карта уже использована"; +"failure.redeem.claimed.message" = "Похоже, эту карту уже использовали с другой учетной записи. Попробуйте ввести другой PIN."; +"failure.submit" = "ВОЗВРАТ"; + +"unreachable.vc_title" = "Ошибка"; +"unreachable.title" = "Ой!"; +"unreachable.message" = "Интернет-соединение не найдено. Пожалуйста, убедитесь, что у вас есть подключение к Интернету, и повторите попытку позже.\n\nМожно вернуться в приложение позже и завершить процесс."; +"unreachable.submit" = "ПОВТОРИТЬ"; + +"purchase.uncredited.alert.message" = "У вас есть непроведенные транзакции. Хотите восстановить данные своей учетной записи?"; +"purchase.uncredited.alert.button.cancel" = "Отмена"; +"purchase.uncredited.alert.button.recover" = "Восстановить учетную запись"; + +"purchase.trials.intro" = "Начните 7-дневную бесплатную пробу"; +"purchase.trials.price.after" = "После этого %@"; +"purchase.trials.money.back" = "30-дневная гарантия возврата денег"; +"purchase.trials.1year.protection" = "1 год защиты конфиденциальности и личных данных"; +"purchase.trials.anonymous" = "Пользуйтесь Интернетом анонимно и скрывайте свой IP-адрес."; +"purchase.trials.devices" = "Поддержка сразу 10 устройств"; +"purchase.trials.devices.description" = "Защищайте себя на нескольких устройствах одновременно (до 10)."; +"purchase.trials.region" = "Простое подключение к любому региону"; +"purchase.trials.servers" = "Более 3300 серверов в 32 странах"; +"purchase.trials.start" = "Запустить подписку."; +"purchase.trials.all.plans" = "Смотреть все доступные планы"; + +"purchase.subscribe.now" = "Подписаться"; + +// WALKTHROUGH + +"walkthrough.action.next" = "ДАЛЕЕ"; +"walkthrough.action.done" = "ГОТОВО"; +"walkthrough.action.skip" = "ПРОПУСК"; + +"walkthrough.page.1.title" = "Поддержка 10 устройств одновременно"; +"walkthrough.page.1.description" = "Защищайте себя на нескольких устройствах одновременно (до 10)."; +"walkthrough.page.2.title" = "Простое подключение к любому региону"; +"walkthrough.page.2.description" = "У нас есть серверы по всему миру, так что вы всегда будете под защитой."; +"walkthrough.page.3.title" = "Защита от рекламы"; +"walkthrough.page.3.description" = "Активация нашего правила блокирования контента препятствует отображению рекламы в Safari."; + +"share.data.buttons.accept" = "Принять"; +"share.data.buttons.noThanks" = "Спасибо, не надо"; +"share.data.buttons.readMore" = "Подробнее"; +"share.data.text.title" = "Помогите нам сделать нашу службу еще лучше"; +"share.data.text.description" = "Вы можете анонимно делиться с нами своей статистикой соединения, чтобы помочь нам обеспечить производительность подключения нашей службы. Эти отчеты не включают какую-либо личную информацию."; +"share.data.text.footer" = "Вы всегда можете управлять этим параметром через настройки"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/ru.lproj/Welcome.strings b/Resources/Resources/iOS/ru.lproj/Welcome.strings new file mode 100644 index 000000000..cd0684978 --- /dev/null +++ b/Resources/Resources/iOS/ru.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "Войдите в свою учетную запсь"; +"login.username.placeholder" = "Имя пользователя (p1234567)"; +"login.password.placeholder" = "Пароль"; +"login.submit" = "ВХОД"; +"login.restore.button" = "Не получили данные учетной записи?"; +"login.error.title" = "Войти"; +"login.error.validation" = "Нужно ввести имя пользователя и пароль."; +"login.error.unauthorized" = "Неправильное имя пользователя или пароль."; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "Выполните вход по квитанции о покупке"; +"login.magic.link.title" = "Войти через волшебную ссылку из письма"; +"login.magic.link.response" = "Поищите ссылку для входа в письме."; +"login.magic.link.send" = "Отправить ссылку"; +"login.magic.link.invalid.email" = "Недействительный эл. адрес. Повторите попытку."; + +"purchase.title" = "Выберите план VPN"; +"purchase.subtitle" = "30-дневная гарантия возврата денег"; +"purchase.email.placeholder" = "Адрес эл. почты"; +"purchase.continue" = "Продолжить"; +"purchase.login.footer" = "Уже есть учетная запись?"; +"purchase.login.button" = "Вход"; +"purchase.error.title" = "Купить"; +"purchase.error.validation" = "Укажите адрес эл. почты."; +"purchase.error.connectivity.title" = "Ошибка подключения"; +"purchase.error.connectivity.description" = "Не удалось подключиться к Private Internet Access. Это может быть из-за плохого качества соединения с Интернетом, или наша служба заблокирована в вашей стране."; +"purchase.confirm.form.email" = "Введите свой адрес эл. почты"; +"purchase.confirm.plan" = "Вы приобретаете план «%@»"; +"purchase.email.why" = "Нам нужен ваш электронный адрес, чтобы мы могли прислать вам имя пользователя и пароль."; +"purchase.submit" = "Отправить"; +"purchase.or" = "или"; + +"upgrade.header" = "С возвращением!"; +"upgrade.title" = "Чтобы пользоваться Private Internet Access, вам необходимо продлить подписку."; +"upgrade.renew.now" = "Продлить"; + + + +"redeem.title" = "Исп-ть подарочную карту"; +"redeem.subtitle" = "Введите свой адрес эл. почты и %lu-зн. PIN-код с подарочной или триальной карты."; +"redeem.email.placeholder" = "Адрес эл. почты"; +"redeem.submit" = "ОТПРАВИТЬ"; +"redeem.error.title" = "Использовать"; +"redeem.error.code" = "В коде должно быть %lu цифр(ы)."; +"redeem.error.allfields" = "Введите свой эл. адрес и PIN-код карты"; +"redeem.accessibility.back" = "Назад"; +"redeem.giftcard.placeholder" = "PIN-код подарочной карты"; + +"plan.monthly.title" = "Ежемесячно"; +"plan.yearly.title" = "Ежегодно"; +"plan.yearly.detail_format" = "%@%@ в год"; +"plan.price_format" = "%@/мес."; +"plan.best_value" = "Максимальная выгода"; +"plan.accessibility.per_month" = "в месяц"; + +"restore.title" = "Восстановить непроведенную покупку"; +"restore.subtitle" = "Если вы купили план через это приложение и не получили учетных данных, вы можете повторно отправить их отсюда. За эту процедуру не взимается плата."; +"restore.email.placeholder" = "Адрес электронной почты"; +"restore.submit" = "ПОДТВЕРДИТЬ"; + +"iap.error.message.unavailable" = "Серверы Apple временно недоступны. Повторите попытку позже."; +"iap.error.title" = "Ошибка"; + +"agreement.trials.title" = "Положения и условия бесплатного пробного пользования"; +"agreement.trials.message" = "Платеж списывается со счета вашего Apple ID при подтверждении покупки. Подписка продлевается автоматически, если не отменить ее по меньшей мере за 24 часа до окончания текущего периода. Плата за продление подписки будет списана со счета вашей учетной записи в течение 24 часов до окончания текущего периода. Для управления подписками, в том числе их отмены, после покупки перейдите в настройки учетной записи в App Store.\n\nНекоторые платные подписки могут предлагать бесплатное пробное пользование перед тем, как списывать средства с использованием указанного вами способа оплаты. Если вы решите отменить платную подписку до того, как мы начнем списывать средства с использованием указанного вами способа оплаты, сделайте это по меньшей мере за 24 часа до окончания бесплатного пробного периода.\n\nБесплатное пробное пользование доступно только для новых пользователей и предлагается по нашему единоличному усмотрению, и если вы попытаетесь зарегистрироваться для участия в дополнительном бесплатном пробном пользовании, с вас будет незамедлительно списана стандартная стоимость подписки.\n\nМы оставляем за собой право в любое время прервать ваше бесплатное пробное пользование.\n\nНеиспользованная часть бесплатного пробного периода сгорает после приобретения подписки.\n\nЗарегистрировавшись, вы тем самым принимаете настоящие положения и условия."; +"agreement.message" = "После завершения 7-дневного бесплатного пробного периода подписка автоматически продлевается на %@, если не отменить ее по меньшей мере за 24 часа до окончания текущего периода. Плата за продление подписки будет списана со счета вашей учетной записи в течение 24 часов до окончания текущего периода. Для управления подписками, в том числе их отмены, после покупки перейдите в настройки учетной записи в App Store. 7-дневное пробное пользование предлагается каждому пользователю только 1 раз. Неиспользованная часть бесплатного пробного периода сгорает после приобретения подписки. Цена указывается с учетом местных налогов на продажу.\n\nРегистрируясь, вы тем самым принимаете списание с вашего счета сумм в $1 и $2 доллара США."; +"agreement.trials.yearly.plan" = "год"; +"agreement.trials.monthly.plan" = "месяц"; + +"agreement.message.tos" = "Условия использования"; +"agreement.message.privacy" = "Политика конфиденциальности"; + +"getstarted.buttons.buyaccount" = "Приобрести учетную запись"; + +"gdpr.collect.data.title" = "Личная информация, которую мы собираем"; +"gdpr.collect.data.description" = "Адрес эл. почты используется в целях управления учетной записью и защиты от злоупотреблений."; +"gdpr.usage.data.title" = "Использование собираемой нами личной информации"; +"gdpr.usage.data.description" = "Адрес эл. почты используется исключительно для отправки информации о подписке, подтверждений оплаты, переписки с пользователем и отправки акционных предложений Private Internet Access."; +"gdpr.accept.button.title" = "Принять и продолжить"; + +"update.account.email.error" = "Не удалось изменить эл. адрес учетной записи"; diff --git a/Resources/Resources/iOS/th.lproj/Signup.strings b/Resources/Resources/iOS/th.lproj/Signup.strings new file mode 100644 index 000000000..520a4ea39 --- /dev/null +++ b/Resources/Resources/iOS/th.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "ยืนยันการสมัคร"; +"in_progress.message" = "เรากำลังยืนยันการซื้อของคุณกับระบบของเรา กรุณารอสักครู่"; +"in_progress.redeem.message" = "เรากำลังยืนยัน PIN การ์ดของคุณกับระบบของเรา กรุณารอสักครู่"; + +"success.title" = "ซื้อสำเร็จ"; +"success.message_format" = "ขอบคุณที่สมัครสมาชิกกับเรา เราได้ส่งชื่อผู้ใช้และรหัสผ่านไปยังอีเมลของคุณแล้วที่ %@"; +"success.redeem.title" = "คืนบัตรเสร็จสมบูรณ์!"; +"success.redeem.message" = "คุณจะได้รับอีเมลพร้อมชื่อผู้ใช้และรหัสผ่านในไม่ช้า\n\nข้อมูลการล็อกอิน"; +"success.username.caption" = "ชื่อผู้ใช้"; +"success.password.caption" = "รหัสผ่าน"; +"success.submit" = "เริ่มใช้งาน"; + +"failure.vc_title" = "การสมัครล้มเหลว"; +"failure.title" = "สร้างบัญชีผู้ใช้ไม่สำเร็จ"; +"failure.message" = "เราไม่สามารถสร้างบัญชีได้ในขณะนี้ กรุณาลองใหม่อีกครั้งภายหลัง การปิดเปิดแอปใหม่จะเป็นการพยายามสร้างบัญชีใหม่"; +"failure.purchase.sandbox.message" = "ไม่มีระบบสมาชิก Sandbox ที่คุณเลือกอยู่ในการผลิต"; +"failure.redeem.invalid.title" = "PIN การ์ดไม่ถูกต้อง"; +"failure.redeem.invalid.message" = "ดูเหมือนว่าคุณใส่ PIN การ์ดไม่ถูกต้อง กรุณาลองใหม่"; +"failure.redeem.claimed.title" = "บัตรมีการใช้สิทธิ์แล้ว"; +"failure.redeem.claimed.message" = "ดูเหมือนว่าบัตรนี้มีการใช้สิทธิ์แล้วโดยบัญชีอื่น กรุณาลองใส่ PIN อื่น"; +"failure.submit" = "ย้อนกลับ"; + +"unreachable.vc_title" = "ข้อผิดพลาด"; +"unreachable.title" = "อุ๊ปส์!"; +"unreachable.message" = "ไม่พบการเชื่อมต่ออินเทอร์เน็ต กรุณายืนยันว่าคุณมีการเชื่อมต่ออินเทอร์เน็ตแล้วกดลองอีกครั้งด้านล่างนี้\n\nคุณสามารถกลับมาใหม่ในภายหลังเพื่อดำเนินการต่อให้เสร็จ"; +"unreachable.submit" = "ลองใหม่"; + +"purchase.uncredited.alert.message" = "คุณได้ยกเลิกการทำธุรกรรมแล้ว คุณต้องการกู้คืนรายละเอียดบัญชีหรือไม่"; +"purchase.uncredited.alert.button.cancel" = "ยกเลิก"; +"purchase.uncredited.alert.button.recover" = "กู้คืนบัญชี"; + +"purchase.trials.intro" = "เริ่มทดลองใช้ฟรี 7 วัน"; +"purchase.trials.price.after" = "จากนั้น %@"; +"purchase.trials.money.back" = "รับประกันการคืนเงินภายใน 30 วัน"; +"purchase.trials.1year.protection" = "การป้องกันข้อมูลประจำตัวและความเป็นส่วนตัว 1 ปี"; +"purchase.trials.anonymous" = "เรียกดูโดยไม่ระบุชื่อและซ่อน ip ของคุณ"; +"purchase.trials.devices" = "รับรองอุปกรณ์ 10 เครื่องในเวลาเดียวกัน"; +"purchase.trials.devices.description" = "ปกป้องตัวคุณบนอุปกรณ์ถึง 10 เครื่องในเวลาเดียวกัน"; +"purchase.trials.region" = "เชื่อมต่อไปยังภูมิภาคใดก็ตามได้อย่างง่ายดาย"; +"purchase.trials.servers" = "กว่า 3300 เซิร์ฟเวอร์ใน 32 ประเทศ"; +"purchase.trials.start" = "เริ่มการเป็นสมาชิก"; +"purchase.trials.all.plans" = "ดูแผนที่มีทั้งหมด"; + +"purchase.subscribe.now" = "สมัครสมาชิกตอนนี้"; + +// WALKTHROUGH + +"walkthrough.action.next" = "ถัดไป"; +"walkthrough.action.done" = "เสร็จสิ้น"; +"walkthrough.action.skip" = "ข้าม"; + +"walkthrough.page.1.title" = "รับรองอุปกรณ์ 10 เครื่องในคราวเดียว"; +"walkthrough.page.1.description" = "ปกป้องตัวคุณบนอุปกรณ์ถึง 10 เครื่องในเวลาเดียวกัน"; +"walkthrough.page.2.title" = "เชื่อมต่อไปยังภูมิภาคใดก็ตามได้อย่างง่ายดาย"; +"walkthrough.page.2.description" = "ด้วยเซิร์ฟเวอร์ที่มีอยู่ทั่วโลก คุณจะได้รับความคุ้มครองตลอดเวลา"; +"walkthrough.page.3.title" = "ปกป้องตัวคุณจากโฆษณา"; +"walkthrough.page.3.description" = "การเปิดใช้งานตัวปิดกั้นเนื้อหาของเราจะเป็นการป้องกันไม่ให้แสดงโฆษณาใน Safari"; + +"share.data.buttons.accept" = "ยอมรับ"; +"share.data.buttons.noThanks" = "ไม่ล่ะ ขอบคุณ"; +"share.data.buttons.readMore" = "อ่านเพิ่มเติม"; +"share.data.text.title" = "โปรดช่วยเราปรับปรุงบริการของเรา"; +"share.data.text.description" = "เพื่อช่วยให้เรามั่นใจในประสิทธิภาพการเชื่อมต่อของบริการของเรา คุณสามารถแชร์สถิติการเชื่อมต่อของคุณกับเราโดยไม่ระบุชื่อ รายงานเหล่านี้ไม่รวมข้อมูลส่วนบุคคลที่สามารถระบุตัวตนได้"; +"share.data.text.footer" = "คุณสามารถควบคุมสิ่งนี้ได้จากการตั้งค่าของคุณ"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/th.lproj/Welcome.strings b/Resources/Resources/iOS/th.lproj/Welcome.strings new file mode 100644 index 000000000..637de14e0 --- /dev/null +++ b/Resources/Resources/iOS/th.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "ลงชื่อเข้าใช้บัญชีของคุณ"; +"login.username.placeholder" = "ชื่อผู้ใช้ (p1234567)"; +"login.password.placeholder" = "รหัสผ่าน"; +"login.submit" = "เข้าสู่ระบบ"; +"login.restore.button" = "ยังไม่ได้รับรายละเอียดบัญชีหรือ"; +"login.error.title" = "เข้าสู่ระบบ"; +"login.error.validation" = "คุณต้องกรอกชื่อผู้ใช้และรหัสผ่าน"; +"login.error.unauthorized" = "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "เข้าสู่ระบบโดยใช้ใบเสร็จรับเงิน"; +"login.magic.link.title" = "เข้าสู่ระบบโดยใช้ลิงก์อีเมลวิเศษ"; +"login.magic.link.response" = "โปรดตรวจสอบอีเมลของคุณเพื่อดูลิงค์สำหรับเข้าสู่ระบบ"; +"login.magic.link.send" = "ส่งลิงก์"; +"login.magic.link.invalid.email" = "อีเมลไม่ถูกต้อง กรุณาลองอีกครั้ง"; + +"purchase.title" = "เลือกแผน VPN"; +"purchase.subtitle" = "รับประกันการคืนเงินภายใน 30 วัน"; +"purchase.email.placeholder" = "อีเมลแอดเดรส"; +"purchase.continue" = "ดำเนินการต่อ"; +"purchase.login.footer" = "มีบัญชีแล้วหรือยัง"; +"purchase.login.button" = "ลงชื่อเข้าใช้"; +"purchase.error.title" = "ซื้อ"; +"purchase.error.validation" = "คุณต้องใส่ที่อยู่อีเมล"; +"purchase.error.connectivity.title" = "ความล้มเหลวในการเชื่อมต่อ"; +"purchase.error.connectivity.description" = "เราไม่สามารถเข้าถึง Private Internet Access ซึ่งอาจเป็นเพราะอินเทอร์เน็ตไม่เสถียรหรือบริการของเราถูกบล็อกในประเทศของคุณ"; +"purchase.confirm.form.email" = "กรุณากรอกอีเมลของคุณ"; +"purchase.confirm.plan" = "คุณกำลังซื้อแผน %@"; +"purchase.email.why" = "โปรดแจ้งอีเมลสำหรับส่งชื่อผู้ใช้และรหัสผ่านของคุณ"; +"purchase.submit" = "ส่ง"; +"purchase.or" = "หรือ"; + +"upgrade.header" = "ยินดีต้อนรับกลับมา!"; +"upgrade.title" = "หากต้องการใช้ Private Internet Access คุณจะต้องต่ออายุสมาชิกของคุณ"; +"upgrade.renew.now" = "ต่ออายุตอนนี้"; + + + +"redeem.title" = "ใช้สิทธิ์บัตรของขวัญ"; +"redeem.subtitle" = "พิมพ์ที่อยู่อีเมลของคุณและ PIN %lu หลักจากบัตรของขวัญหรือบัตรทดลองด้านล่าง"; +"redeem.email.placeholder" = "ที่อยู่อีเมล"; +"redeem.submit" = "ส่ง"; +"redeem.error.title" = "ใช้สิทธิ์"; +"redeem.error.code" = "รหัสต้องประกอบด้วยตัวเลข %lu หลัก"; +"redeem.error.allfields" = "กรุณากรอกอีเมลและ PIN"; +"redeem.accessibility.back" = "กลับ"; +"redeem.giftcard.placeholder" = "PIN บัตรของขวัญ"; + +"plan.monthly.title" = "รายเดือน"; +"plan.yearly.title" = "รายปี"; +"plan.yearly.detail_format" = "%@%@ ต่อปี"; +"plan.price_format" = "%@/เดือน"; +"plan.best_value" = "คุ้มค่าที่สุด"; +"plan.accessibility.per_month" = "ต่อเดือน"; + +"restore.title" = "คืนค่าการซื้อยังไม่ได้คิดเครดิต"; +"restore.subtitle" = "หากคุณทำการซื้อแผนผ่านแอพนี้และยังไม่ได้รับข้อมูลประจำตัว คุณสามารถส่งอีกครั้งได้จากที่นี่ คุณจะไม่ถูกเรียกเก็บเงินซ้ำอีกครั้งในกระบวนการนี้"; +"restore.email.placeholder" = "อีเมลแอดเดรส"; +"restore.submit" = "ยืนยัน"; + +"iap.error.message.unavailable" = "ไม่พบเซิร์ฟเวอร์แอปเปิ้ลในขณะนี้ โปรดลองใหม่ภายหลัง"; +"iap.error.title" = "ข้อผิดพลาด"; + +"agreement.trials.title" = "ข้อกำหนดและเงื่อนไขการทดลองใช้ฟรี"; +"agreement.trials.message" = "ยอดชำระเงินจะถูกหักจากบัญชี Apple ID ของคุณเมื่อมีการยืนยันคำสั่งซื้อ ระบบจะต่ออายุสมาชิกโดยอัตโนมัติเว้นแต่จะมีการยกเลิกล่วงหน้าอย่างน้อย 24 ชั่วโมงก่อนที่จะสิ้นสุดรอบใช้งานปัจจุบัน บัญชีของคุณจะถูกเรียกเก็บเงินค่าต่ออายุสมาชิกภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบใช้งานปัจจุบัน คุณสามารถจัดการและยกเลิกการเป็นสมาชิกได้โดยไปที่การตั้งค่าบัญชีใน App Store หลังจากซื้อแล้ว\n\nบางระบบสมาชิกแบบชำระเงินอาจเสนอให้คุณทดลองใช้ฟรีก่อนที่จะเรียกเก็บเงินผ่านช่องทางการชำระเงินที่คุณเลือกไว้ หากคุณตัดสินใจที่จะยกเลิกการสมัครสมาชิกแบบชำระเงินก่อนที่เราจะเริ่มเรียกเก็บเงินผ่านช่องทางการชำระเงินที่เลือกไว้ ให้ทำการยกเลิกสมาชิกล่วงหน้าอย่างน้อย 24 ชั่วโมงก่อนที่ช่วงทดลองใช้ฟรีจะสิ้นสุดลง\n\nสามารถทดลองใช้ฟรีเฉพาะผู้ใช้ใหม่เท่านั้นและขึ้นอยู่กับดุลยพินิจของเราแต่เพียงผู้เดียว และหากคุณพยายามที่จะสมัครเพื่อทดลองใช้ฟรีซ้ำอีก คุณจะถูกเรียกเก็บค่าธรรมเนียมการสมัครสมาชิกตามมาตรฐานทันที\n\nเราขอสงวนสิทธิ์ในการเพิกถอนสิทธิ์ทดลองใช้ฟรีของคุณได้ตลอดเวลา\n\nส่วนที่ไม่ได้ใช้งานของช่วงทดลองใช้ฟรีจะถูกหักทิ้งเมื่อมีการสมัครสมาชิก\n\nการสมัครสมาชิกถือว่าเป็นการยอมรับข้อกำหนดและเงื่อนไขนี้"; +"agreement.message" = "หลังจากทดลองใช้ฟรี 7 วัน ระบบจะต่ออายุสมาชิกนี้โดยอัตโนมัติในราคา %@ เว้นแต่จะมีการยกเลิกล่วงหน้าอย่างน้อย 24 ชั่วโมงก่อนที่จะสิ้นสุดรอบใช้งานปัจจุบัน บัญชี Apple ID ของคุณจะถูกเรียกเก็บเงินค่าต่ออายุสมาชิกภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบใช้งานปัจจุบัน คุณสามารถจัดการและยกเลิกการเป็นสมาชิกได้โดยไปที่การตั้งค่าบัญชีใน App Store หลังจากซื้อแล้ว จำกัดสิทธิ์การทดลองใช้ฟรี 7 วัน เพียง 1 สิทธิ์ต่อผู้ใช้หนึ่งราย ส่วนที่ไม่ได้ใช้งานของช่วงทดลองใช้ฟรีหากมีให้จะถูกริบเมื่อผู้ใช้ซื้อการสมัครสมาชิก ราคาทั้งหมดรวมภาษีการขายในท้องที่\n\nการลงทะเบียนจะถือว่าคุณยินยอมตาม $1 และ $2"; +"agreement.trials.yearly.plan" = "ปี"; +"agreement.trials.monthly.plan" = "เดือน"; + +"agreement.message.tos" = "ข้อตกลงการใช้บริการ"; +"agreement.message.privacy" = "นโยบายความเป็นส่วนตัว"; + +"getstarted.buttons.buyaccount" = "ซื้อบัญชี"; + +"gdpr.collect.data.title" = "ข้อมูลส่วนบุคคลที่เรารวบรวม"; +"gdpr.collect.data.description" = "อีเมลเพื่อจุดประสงค์ในการจัดการและการป้องกันบัญชีจากการใช้งานในทางที่ผิด"; +"gdpr.usage.data.title" = "การใช้ข้อมูลส่วนบุคคลที่เรารวบรวม"; +"gdpr.usage.data.description" = "ที่อยู่อีเมลใช้ในการส่งข้อมูลการสมัครสมาชิก การยืนยันการชำระเงิน การติดต่อกับลูกค้า และข้อเสนอส่งเสริมการขาย Private Internet Access เท่านั้น"; +"gdpr.accept.button.title" = "ยอมรับและดำเนินการต่อ"; + +"update.account.email.error" = "ไม่สามารถแก้ไขอีเมลบัญชีได้"; diff --git a/Resources/Resources/iOS/tr.lproj/Signup.strings b/Resources/Resources/iOS/tr.lproj/Signup.strings new file mode 100644 index 000000000..36d6ad53a --- /dev/null +++ b/Resources/Resources/iOS/tr.lproj/Signup.strings @@ -0,0 +1,166 @@ +/* (No Comment) */ +"failure.message" = "Şu anda hesap oluşturamıyoruz.\nLütfen daha sonra tekrar deneyin.\n\nUygulama yeniden açıldığından hesap oluşturma tekrar denenecektir."; + +/* (No Comment) */ +"failure.purchase.sandbox.message" = "Seçilen Sandbox aboneliği üretim ortamında mevcut değil."; + +/* (No Comment) */ +"failure.redeem.claimed.message" = "Bu kart önceden başka bir hesap tarafından talep edilmiş. Farklı bir PIN girmeyi deneyebilirsiniz."; + +/* (No Comment) */ +"failure.redeem.claimed.title" = "Kart önceden talep edilmiş"; + +/* (No Comment) */ +"failure.redeem.invalid.message" = "Görünüşe bakılırsa geçersiz bir kart PIN'i girdiniz. Lütfen tekrar deneyin."; + +/* (No Comment) */ +"failure.redeem.invalid.title" = "Geçersiz kart PIN'i"; + +/* (No Comment) */ +"failure.submit" = "GERİ DÖN"; + +/* (No Comment) */ +"failure.title" = "Hesap Oluşturma Hatası"; + +/* (No Comment) */ +"failure.vc_title" = "Kaydolma başarısız oldu"; + +/* (No Comment) */ +"in_progress.message" = "Sistemimizle satın alım işleminizi onaylıyoruz. Biraz zaman alabilir; lütfen bekleyin."; + +/* (No Comment) */ +"in_progress.redeem.message" = "Kart PIN'inizi sistemimizde onaylıyoruz. Bu biraz zaman alabilir, lütfen bekleyin."; + +/* Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. */ +"in_progress.title" = "Kaydolmayı onayla"; + +/* (No Comment) */ +"purchase.subscribe.now" = "Hemen abone ol"; + +/* (No Comment) */ +"purchase.trials.1year.protection" = "1 yıllık gizlilik ve kimlik koruması"; + +/* (No Comment) */ +"purchase.trials.all.plans" = "Tüm mevcut planlara bakın"; + +/* (No Comment) */ +"purchase.trials.anonymous" = "IP'nizi gizleyerek İnternet'te isimsiz gezinin."; + +/* (No Comment) */ +"purchase.trials.devices" = "Aynı anda 10 cihaz desteği"; + +/* (No Comment) */ +"purchase.trials.devices.description" = "Aynı anda 10 cihazda kendinizi koruyun."; + +/* (No Comment) */ +"purchase.trials.intro" = "7 günlük ücretsiz deneme sürenizi başlatın"; + +/* (No Comment) */ +"purchase.trials.money.back" = "30 günlük para iade garantisi"; + +/* (No Comment) */ +"purchase.trials.price.after" = "Ardından %@"; + +/* (No Comment) */ +"purchase.trials.region" = "Tüm bölgelere kolayca bağlanın"; + +/* (No Comment) */ +"purchase.trials.servers" = "32 ülkede en az 3.300 sunucu"; + +/* (No Comment) */ +"purchase.trials.start" = "Aboneliği başlat"; + +/* (No Comment) */ +"purchase.uncredited.alert.button.cancel" = "İptal"; + +/* (No Comment) */ +"purchase.uncredited.alert.button.recover" = "Hesabı kurtar"; + +/* (No Comment) */ +"purchase.uncredited.alert.message" = "Hesaba yansıtılmamış olan işlemleriniz var. Hesap bilgilerinizi kurtarmak ister misiniz?"; + +/* (No Comment) */ +"share.data.buttons.accept" = "Kabul Et"; + +/* (No Comment) */ +"share.data.buttons.noThanks" = "Hayır, teşekkürler"; + +/* (No Comment) */ +"share.data.buttons.readMore" = "Devamını oku"; + +/* (No Comment) */ +"share.data.readMore.text.description" = "Bu asgari bilgi, potansiyel bağlantı sorunlarını tanımlayıp düzeltmemize yardımcı olur. Bu bilgiyi paylaşmak için onay verilmesi ve varsayılan olarak kapalı olduğu için elle etkinleştirilmesi gerektiğini dikkate alın.\n\nŞu olaylarla ilgili bilgi toplayacağız:\n\n - Bağlantı Denemesi\n - Bağlantı İptal Edildi\n - Bağlantı Kuruldu\n\nTüm bu olaylar için şu bilgileri toplayacağız:\n - Platform\n - Uygulama sürümü\n - Uygulama türü (ön sürüm olup olmadığı)\n - Kullanılan protokol\n - Bağlantı kaynağı (manuel ya da otomasyon ile)\n\nTüm olaylarda rastgele oluşturulan eşsiz bir kimlik yer alacak. Bu kimlik kullanıcı hesabınızla bağlantılı değildir. Bu eşsiz kimlik, gizliliğin korunması açısından günlük olarak üretilir.\n\nKontrol daima sizde olacak. Ayarlardan hangi verileri topladığımızı görebilir ve bunu istediğiniz zaman kapatabilirsiniz."; + +/* (No Comment) */ +"share.data.text.description" = "Hizmetimizin bağlantı performansını korumamıza yardımcı olmak için bağlantı istatistiklerinizi isimsiz olarak bizimle paylaşabilirsiniz. Bu raporlarda kişiyi tanımlayabilecek herhangi bir bilgi yer almaz."; + +/* (No Comment) */ +"share.data.text.footer" = "Bunu istediğiniz zaman ayarlarınızdan kontrol edebilirsiniz"; + +/* (No Comment) */ +"share.data.text.title" = "Lütfen hizmetimizi geliştirmemize yardım edin"; + +/* (No Comment) */ +"success.message_format" = "Bize kayıt olduğunuz için teşekkürler. Hesap kullanıcı adı ve parolanızı %@ e-posta adresinize gönderdik"; + +/* (No Comment) */ +"success.password.caption" = "Şifre"; + +/* (No Comment) */ +"success.redeem.message" = "Kısa süre içinde kullanıcı adınızı ve şifrenizi içeren bir e-posta alacaksınız.\n\nGiriş bilgileriniz"; + +/* (No Comment) */ +"success.redeem.title" = "Kart başarıyla kullanıldı"; + +/* (No Comment) */ +"success.submit" = "Başlarken"; + +/* (No Comment) */ +"success.title" = "Satın Alma Tamamlandı"; + +/* (No Comment) */ +"success.username.caption" = "Kullanıcı Adı"; + +/* (No Comment) */ +"unreachable.message" = "İnternet bağlantısı yok. Lütfen İnternet bağlantınız olup olmadığını kontrol edin ve tekrar aşağıya tıklamayı deneyin.\n\nİşlemi bitirmek için uygulamaya daha sonra tekrar gelebilirsiniz."; + +/* (No Comment) */ +"unreachable.submit" = "TEKRAR DENE"; + +/* (No Comment) */ +"unreachable.title" = "Heeey!"; + +/* (No Comment) */ +"unreachable.vc_title" = "Hata"; + +/* (No Comment) */ +"walkthrough.action.done" = "BİTTİ"; + +/* WALKTHROUGH */ +"walkthrough.action.next" = "İLERİ"; + +/* (No Comment) */ +"walkthrough.action.skip" = "ATLA"; + +/* (No Comment) */ +"walkthrough.page.1.description" = "Aynı anda 10 cihazda koruma sağlayın."; + +/* (No Comment) */ +"walkthrough.page.1.title" = "Aynı anda 10 cihazı destekler"; + +/* (No Comment) */ +"walkthrough.page.2.description" = "Dünya çapındaki sunucularla daima koruma altındasınız."; + +/* (No Comment) */ +"walkthrough.page.2.title" = "Herhangi bir bölgeye kolayca bağlanın"; + +/* (No Comment) */ +"walkthrough.page.3.description" = "İçerik Engelleyicimizi etkinleştirdiğinizde Safari'de reklamların gösterilmesi engellenir."; + +/* (No Comment) */ +"walkthrough.page.3.title" = "Kendinizi reklamlardan koruyun"; + diff --git a/Resources/Resources/iOS/tr.lproj/Welcome.strings b/Resources/Resources/iOS/tr.lproj/Welcome.strings new file mode 100644 index 000000000..49d7ab5ca --- /dev/null +++ b/Resources/Resources/iOS/tr.lproj/Welcome.strings @@ -0,0 +1,205 @@ +/* (No Comment) */ +"agreement.message" = "Bu abonelik, deneme süresinin sonuna en az 24 saat kalana dek iptal edilmezse, otomatik olarak %@ karşılığında yenilenir. Deneme süresinin sonuna 24 saat kaldıktan sonra, Apple Kimliğinizin hesabından yenileme ücreti alınır. Satın alım işleminden sonra App Store hesap ayarlarına giderek abonelik ayarlarınızı değiştirebilir ve aboneliklerinizi iptal edebilirsiniz. 7 günlük deneme süresi, her kullanıcı için bir tane 7 günlük deneme süresi hakkı ile sınırlıdır. Kullanıcı bir abonelik satın aldığında, teklif edilmişse, ücretsiz deneme süresinin kullanılmayan herhangi bir kısmı geçerliliğini yitirir. Tüm fiyatlara uygulanabilir yerel satış vergileri dahildir.\n\nKaydolduğunuzda, $1 ile $2 unsurlarını kabul etmiş olursunuz."; + +/* (No Comment) */ +"agreement.message.privacy" = "Gizlilik Politikası"; + +/* (No Comment) */ +"agreement.message.tos" = "Hizmet Koşulları"; + +/* (No Comment) */ +"agreement.trials.message" = "Satın alım onaylandıktan sonra, ödeme ücreti, Apple Kimliği hesabınızdan alınır. Mevcut dönemin sonuna en az 24 saat kalana dek iptal edilmezse, abonelik otomatik olarak yenilenir. Mevcut dönemin sonuna 24 saat kaldıktan sonra hesabınızdan yenileme ücreti alınır. Satın alım işleminden sonra App Store'daki hesap ayarlarınıza giderek abonelik ayarlarınızı değiştirebilir ve aboneliğinizi iptal edebilirsiniz.\n\nBelirli Ücretli Abonelik planlarında, seçtiğiniz ödeme yöntemiyle ücret alınmadan önce, bir ücretsiz kullanım süresi sunulabilir. Seçtiğiniz ödeme yöntemiyle sizden ücret almaya başlamamızdan önce Ücretli Aboneliğinizi iptal etmek isterseniz, ücretsiz kullanım süresinin sonuna en az 24 saat kalana dek aboneliğinizi iptal etmelisiniz.\n\nÜcretsiz deneme süresinden sadece yeni kullanıcılar faydalanabilir ve bu tamamen bizim takdirimizdedir. Tekrar kaydolarak bir ücretsiz deneme süresi daha almaya çalışırsanız, standart Abonelik Ücreti anında hesabınızdan düşülür.\n\nÜcretsiz deneme sürenizi istediğimiz zaman iptal etme hakkına sahibiz.\n\nBir abonelik satın aldığınızda, ücretsiz kullanım sürenizin kullanılmayan kısmını yitirirsiniz.\n\nKaydolduğunuzda bu şart ve koşulları kabul etmiş olursunuz."; + +/* (No Comment) */ +"agreement.trials.monthly.plan" = "ay"; + +/* (No Comment) */ +"agreement.trials.title" = "Ücretsiz deneme süresi şart ve koşulları"; + +/* (No Comment) */ +"agreement.trials.yearly.plan" = "yıl"; + +/* (No Comment) */ +"gdpr.accept.button.title" = "Kabul edip devam et"; + +/* (No Comment) */ +"gdpr.collect.data.description" = "Hesap yönetimi ve ihlalden koruma için E-posta Adresi."; + +/* (No Comment) */ +"gdpr.collect.data.title" = "Topladığımız kişisel bilgiler"; + +/* (No Comment) */ +"gdpr.usage.data.description" = "E-posta adresi sadece abonelik bilgilerinin, ödeme onaylarının, müşteri iletişim unsurlarının ve Private Internet Access'in promosyonel tekliflerinin gönderilmesi için kullanılır."; + +/* (No Comment) */ +"gdpr.usage.data.title" = "Tarafımızca toplanan kişisel bilgilerin kullanım şekilleri"; + +/* (No Comment) */ +"getstarted.buttons.buyaccount" = "Hesap satın al"; + +/* (No Comment) */ +"iap.error.message.unavailable" = "Apple sunucuları şu anda kullanılamıyor. Lütfen daha sonra tekrar deneyin."; + +/* (No Comment) */ +"iap.error.title" = "Hata"; + +/* (No Comment) */ +"login.error.throttled" = "Bu kullanıcı adı ile çok fazla kez yanlış giriş yapıldı. Lütfen daha sonra tekrar deneyin."; + +/* (No Comment) */ +"login.error.title" = "Giriş yap"; + +/* (No Comment) */ +"login.error.unauthorized" = "Kullanıcı adınız ya da şifreniz hatalı."; + +/* (No Comment) */ +"login.error.validation" = "Bir kullanıcı adı ve şifre girmelisiniz."; + +/* (No Comment) */ +"login.magic.link.invalid.email" = "E-posta adresi geçersiz. Lütfen tekrar deneyin."; + +/* (No Comment) */ +"login.magic.link.response" = "Giriş linkini bulmak için lütfen e-postalarınıza bakın."; + +/* (No Comment) */ +"login.magic.link.send" = "Link Gönder"; + +/* (No Comment) */ +"login.magic.link.title" = "Sihirli e-posta linki ile giriş yap"; + +/* (No Comment) */ +"login.password.placeholder" = "Şifre"; + +/* (No Comment) */ +"login.receipt.button" = "Satın alım faturasıyla giriş yapın"; + +/* (No Comment) */ +"login.restore.button" = "Hesap bilgilerinizi almadınız mı?"; + +/* (No Comment) */ +"login.submit" = "GİRİŞ YAP"; + +/* Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. */ +"login.title" = "Hesabınıza giriş yapın"; + +/* (No Comment) */ +"login.username.placeholder" = "Kullanıcı Adı (p1234567)"; + +/* (No Comment) */ +"plan.accessibility.per_month" = "aylık"; + +/* (No Comment) */ +"plan.best_value" = "En iyi fiyat"; + +/* (No Comment) */ +"plan.monthly.title" = "Aylık"; + +/* (No Comment) */ +"plan.price_format" = "%@/ay"; + +/* (No Comment) */ +"plan.yearly.detail_format" = "Yılda %@%@"; + +/* (No Comment) */ +"plan.yearly.title" = "Yıllık"; + +/* (No Comment) */ +"purchase.confirm.form.email" = "E-posta adresinizi girin"; + +/* (No Comment) */ +"purchase.confirm.plan" = "%@ planını satın alıyorsunuz"; + +/* (No Comment) */ +"purchase.continue" = "Devam et"; + +/* (No Comment) */ +"purchase.email.placeholder" = "E-posta adresi"; + +/* (No Comment) */ +"purchase.email.why" = "Kullanıcı adınızla şifrenizi gönderebilmemiz için e-posta adresinize ihtiyacımız var."; + +/* (No Comment) */ +"purchase.error.connectivity.description" = "Özel İnternet Erişimi'ne ulaşamıyoruz. Bu zayıf internet yüzünden olabilir veya hizmetimiz ülkenizde engelleniyor."; + +/* (No Comment) */ +"purchase.error.connectivity.title" = "Bağlantı Hatası"; + +/* (No Comment) */ +"purchase.error.title" = "Satın Al"; + +/* (No Comment) */ +"purchase.error.validation" = "Bir e-posta adresi girmeniz gerekiyor."; + +/* (No Comment) */ +"purchase.login.button" = "Giriş yapın"; + +/* (No Comment) */ +"purchase.login.footer" = "Hesabınız var mı?"; + +/* (No Comment) */ +"purchase.or" = "veya"; + +/* (No Comment) */ +"purchase.submit" = "Gönder"; + +/* (No Comment) */ +"purchase.subtitle" = "30 günlük para iade garantisi"; + +/* (No Comment) */ +"purchase.title" = "Bir VPN planı seçin"; + +/* (No Comment) */ +"redeem.accessibility.back" = "Geri"; + +/* (No Comment) */ +"redeem.email.placeholder" = "E-posta adresi"; + +/* (No Comment) */ +"redeem.error.allfields" = "Lütfen e-posta adresinizi ve kart PIN numaranızı girin."; + +/* (No Comment) */ +"redeem.error.code" = "Kod, %lu sayısal haneden oluşmalıdır."; + +/* (No Comment) */ +"redeem.error.title" = "Kullan"; + +/* (No Comment) */ +"redeem.giftcard.placeholder" = "Hediye kartı ve PIN"; + +/* (No Comment) */ +"redeem.submit" = "Gönder"; + +/* (No Comment) */ +"redeem.subtitle" = "E-posta adresinizi ve hediye kartınızdaki ya da deneme kartınızdaki %lu haneli PIN'i aşağıya girin."; + +/* (No Comment) */ +"redeem.title" = "Hediye kartını kullan"; + +/* (No Comment) */ +"restore.email.placeholder" = "E-posta adresi"; + +/* (No Comment) */ +"restore.submit" = "ONAYLA"; + +/* (No Comment) */ +"restore.subtitle" = "Bu uygulamadan bir plan satın aldıktan sonra hesap bilgilerinizi alamadıysanız, onları buradan tekrar gönderebilirsiniz. Bu işlem esnasında sizden ücret alınmayacak."; + +/* (No Comment) */ +"restore.title" = "Bilgileri gönderilmeyen satın alma işlemini tekrarlayın"; + +/* (No Comment) */ +"update.account.email.error" = "Hesap e-posta adresi değiştirilemedi"; + +/* (No Comment) */ +"upgrade.header" = "Tekrar Hoş Geldiniz!"; + +/* (No Comment) */ +"upgrade.renew.now" = "Hemen yenileyin"; + +/* (No Comment) */ +"upgrade.title" = "Private Internet Access kullanabilmek için aboneliğinizi yenilemeniz gerekiyor."; + diff --git a/Resources/Resources/iOS/zh-Hans.lproj/Signup.strings b/Resources/Resources/iOS/zh-Hans.lproj/Signup.strings new file mode 100644 index 000000000..2f4afbb78 --- /dev/null +++ b/Resources/Resources/iOS/zh-Hans.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "确认注册"; +"in_progress.message" = "我们正在确认您在我们系统中的购买。这可能需要一点时间,请耐心等待。"; +"in_progress.redeem.message" = "我们正在通过系统确认您的卡片PIN。这可能需要一些时间,请耐心等待。"; + +"success.title" = "购买完成"; +"success.message_format" = "感谢注册。我们已将您的用户名和密码发送至您的电子邮箱:%@"; +"success.redeem.title" = "卡片兑换成功"; +"success.redeem.message" = "您将很快收到一封电子邮件,记有您的用户名和密码。\n\n您的登录详情"; +"success.username.caption" = "用户名"; +"success.password.caption" = "密码"; +"success.submit" = "开始体验"; + +"failure.vc_title" = "注册失败"; +"failure.title" = "账户创建失败"; +"failure.message" = "我们现在无法创建账号。\n请稍后再试。\n\n重新打开本应用将会再次尝试创建账号。"; +"failure.purchase.sandbox.message" = "所选的沙盒订阅不适用于生产"; +"failure.redeem.invalid.title" = "卡片PIN无效"; +"failure.redeem.invalid.message" = "您输入的卡片PIN似乎无效。请重试。"; +"failure.redeem.claimed.title" = "卡片已使用"; +"failure.redeem.claimed.message" = "此卡片似乎已被另一个账号使用。您可尝试输入另一个PIN。"; +"failure.submit" = "返回"; + +"unreachable.vc_title" = "错误"; +"unreachable.title" = "糟糕!"; +"unreachable.message" = "未找到网络连接。请确认您已接入网络,然后点击下面的重试。\n\n您可在稍后再回到本应用完成该操作。"; +"unreachable.submit" = "重试"; + +"purchase.uncredited.alert.message" = "你有未入账的的交易。要恢复您的账户详情吗?"; +"purchase.uncredited.alert.button.cancel" = "取消"; +"purchase.uncredited.alert.button.recover" = "恢复账户"; + +"purchase.trials.intro" = "开始 7 天免费试用"; +"purchase.trials.price.after" = "然后 %@"; +"purchase.trials.money.back" = "7 天退款保证"; +"purchase.trials.1year.protection" = "1 年隐私和身份保护"; +"purchase.trials.anonymous" = "匿名浏览并隐藏您的 IP。"; +"purchase.trials.devices" = "一次支持 10 台设备"; +"purchase.trials.devices.description" = "一次在多达 10 台设备上保护自己。"; +"purchase.trials.region" = "轻松连接到任何地区"; +"purchase.trials.servers" = "在 32 个国家h地区拥有超过 3300 台服务器"; +"purchase.trials.start" = "开始订阅"; +"purchase.trials.all.plans" = "查看所有可用套餐"; + +"purchase.subscribe.now" = "立即订阅"; + +// WALKTHROUGH + +"walkthrough.action.next" = "下一个"; +"walkthrough.action.done" = "完成"; +"walkthrough.action.skip" = "跳过"; + +"walkthrough.page.1.title" = "一次支持 10 台设备"; +"walkthrough.page.1.description" = "一次在多达 10 台设备上保护自己。"; +"walkthrough.page.2.title" = "轻松连接到任何地区"; +"walkthrough.page.2.description" = "服务器遍布世界各地,您始终受到保护。"; +"walkthrough.page.3.title" = "让自己远离广告"; +"walkthrough.page.3.description" = "启用内容拦截器以防止 Safari 中出现广告。"; + +"share.data.buttons.accept" = "接受"; +"share.data.buttons.noThanks" = "不用,谢谢"; +"share.data.buttons.readMore" = "阅读更多"; +"share.data.text.title" = "请帮助我们改进服务"; +"share.data.text.description" = "为了帮助我们保持服务的连接性能,您可以匿名与我们共享您的连接统计数据。这些报告不包括任何可识别个人身份的信息。"; +"share.data.text.footer" = "您始终可以从设置中进行控制"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/zh-Hans.lproj/Welcome.strings b/Resources/Resources/iOS/zh-Hans.lproj/Welcome.strings new file mode 100644 index 000000000..8d5c7e113 --- /dev/null +++ b/Resources/Resources/iOS/zh-Hans.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "登录到您的帐户"; +"login.username.placeholder" = "用户名 (p1234567)"; +"login.password.placeholder" = "密码"; +"login.submit" = "登录"; +"login.restore.button" = "没有收到账户详情?"; +"login.error.title" = "登录"; +"login.error.validation" = "您必须输入用户名和密码。"; +"login.error.unauthorized" = "您的用户名或密码不正确。"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "使用购买收据登录"; +"login.magic.link.title" = "使用魔法电子邮件链接登录"; +"login.magic.link.response" = "请检查您的电子邮件,以查找登录链接。"; +"login.magic.link.send" = "发送链接"; +"login.magic.link.invalid.email" = "电子邮箱乎无效。请重试。"; + +"purchase.title" = "选择 VPN 套餐"; +"purchase.subtitle" = "7 天退款保证"; +"purchase.email.placeholder" = "电子邮件地址"; +"purchase.continue" = "继续"; +"purchase.login.footer" = "已有帐号?"; +"purchase.login.button" = "登录"; +"purchase.error.title" = "购买"; +"purchase.error.validation" = "您必须输入一个电子邮箱地址。"; +"purchase.error.connectivity.title" = "连接失败"; +"purchase.error.connectivity.description" = "我们无法接入Private Internet Access。原因可能是互联网连接不良或者我们的服务在您的国家遭到屏蔽。"; +"purchase.confirm.form.email" = "请输入您的电子邮件地址"; +"purchase.confirm.plan" = "您正在购买 %@ 套餐"; +"purchase.email.why" = "我们需要您的电子邮件以发送您的用户名和密码。"; +"purchase.submit" = "提交"; +"purchase.or" = "或"; + +"upgrade.header" = "欢迎回来!"; +"upgrade.title" = "您需要续订才能使用 Private Internet Access。"; +"upgrade.renew.now" = "立即续订"; + + + +"redeem.title" = "兑换礼品卡"; +"redeem.subtitle" = "请输入您的电子邮箱地址以及礼品卡或试用卡上的%lu位数字PIN。"; +"redeem.email.placeholder" = "邮箱地址"; +"redeem.submit" = "提交"; +"redeem.error.title" = "兑换"; +"redeem.error.code" = "PIN码必须包含%lu个数字。"; +"redeem.error.allfields" = "请输入您的电子邮件和卡片 PIN 码。"; +"redeem.accessibility.back" = "返回"; +"redeem.giftcard.placeholder" = "礼品卡 PIN"; + +"plan.monthly.title" = "每月"; +"plan.yearly.title" = "每年"; +"plan.yearly.detail_format" = "%@%@/每年"; +"plan.price_format" = "%@/每月"; +"plan.best_value" = "最超值"; +"plan.accessibility.per_month" = "每月"; + +"restore.title" = "恢复未入账的购买"; +"restore.subtitle" = "如果您通过此 app 购买了套餐,但没有收到凭据,可以从这里重新发送。在此过程中您不会被收费。"; +"restore.email.placeholder" = "电子邮件地址"; +"restore.submit" = "确认"; + +"iap.error.message.unavailable" = "Apple 服务器目前不可用。请稍后重试。"; +"iap.error.title" = "错误"; + +"agreement.trials.title" = "免费试用条款和条件"; +"agreement.trials.message" = "确认购买后,将从您的 Apple ID 账户中收取款项。除非在当前使用期结束前至少提前 24 小时取消,否则会自动续订。您的账户将在当前使用期结束前 24 小时内收取续订费用。您可以在购买后前往 App Store 上的账户设置来管理和取消订阅。\n\n某些“付费订阅”可能会在向您收取款项之前先提供免费试用。如果您在我们开始收取款项之前决定取消订阅“付费订阅”,请在免费试用结束前至少提前 24 小时取消订阅。\n\n免费试用仅适用于新用户,并由我们自行决定,如果您尝试注册额外的免费试用,您将被立即收取标准订阅费。\n\n我们有权随时撤销您的免费试用。\n\n免费试用期的任何未使用部分将在购买订阅时取消。\n\n注册即表示接受上述条款和条件。"; +"agreement.message" = "免费试用 7 天后,除非在试用期结束前至少提前 24 小时取消,否则此订阅将自动续订 %@。您的 Apple ID 账户将在试用期结束前 24 小时内收取续订费用。您可以在购买后前往 App Store 上的账户设置来管理和取消订阅。每个用户仅可享受一次 7 天试用优惠。免费试用期的任何未使用部分(如果提供)将在用户购买订阅时失效。所有价格均包含适用的当地营业税。\n\n注册即表示接受$1和$2。"; +"agreement.trials.yearly.plan" = "年"; +"agreement.trials.monthly.plan" = "月"; + +"agreement.message.tos" = "服务条款"; +"agreement.message.privacy" = "隐私政策"; + +"getstarted.buttons.buyaccount" = "购买账户"; + +"gdpr.collect.data.title" = "我们收集的个人信息"; +"gdpr.collect.data.description" = "用于账户管理和防止滥用的电子邮件地址。"; +"gdpr.usage.data.title" = "我们收集的个人信息的使用方式"; +"gdpr.usage.data.description" = "电子邮件地址仅用于发送订阅信息、付款确认、客户通信以及 Private Internet Access 促销优惠。"; +"gdpr.accept.button.title" = "同意并继续"; + +"update.account.email.error" = "无法修改账户电子邮件"; diff --git a/Resources/Resources/iOS/zh-Hant.lproj/Signup.strings b/Resources/Resources/iOS/zh-Hant.lproj/Signup.strings new file mode 100644 index 000000000..ed78c07e6 --- /dev/null +++ b/Resources/Resources/iOS/zh-Hant.lproj/Signup.strings @@ -0,0 +1,92 @@ +/* + Signup.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"in_progress.title" = "壓認註冊"; +"in_progress.message" = "我們的系統正確認您的購買交易,可能需要停留在此畫面幾分鐘時間。"; +"in_progress.redeem.message" = "我們的系統正在確認您的卡 PIN 碼。這可能需要一點時間,請稍候。"; + +"success.title" = "購買完成"; +"success.message_format" = "感謝您註冊我們的服務!我們已將您的帳戶使用者名稱和密碼寄送到您的電子郵件地址:%@"; +"success.redeem.title" = "已成功兌換禮品卡"; +"success.redeem.message" = "您很快就會收到一封電子郵件,內有使用者名稱及密碼。\n\n您的登入資料"; +"success.username.caption" = "使用者名稱"; +"success.password.caption" = "密碼"; +"success.submit" = "開始使用"; + +"failure.vc_title" = "註冊失敗"; +"failure.title" = "帳戶建立失敗"; +"failure.message" = "我們目前未能建立帳戶,請稍後再試。\n\n應用程式將在重新啟動時再次嘗試建立帳戶。"; +"failure.purchase.sandbox.message" = "所選的沙盒訂閱已不再提供。"; +"failure.redeem.invalid.title" = "無效的卡 PIN 碼"; +"failure.redeem.invalid.message" = "您似乎輸入了一個無效的卡 PIN 碼,請再試一次。"; +"failure.redeem.claimed.title" = "此卡已被使用"; +"failure.redeem.claimed.message" = "這張卡似乎已經被另一個帳戶使用。您可以嘗試輸入不同的 PIN 碼。"; +"failure.submit" = "返回"; + +"unreachable.vc_title" = "錯誤"; +"unreachable.title" = "噢!"; +"unreachable.message" = "找不到網路連線。請確定您已連線上網,然後點選下方按鈕重試。\n\n您可以稍後再回來完成程序。"; +"unreachable.submit" = "重試"; + +"purchase.uncredited.alert.message" = "您有未貸記的交易,要回復帳戶資料嗎?"; +"purchase.uncredited.alert.button.cancel" = "取消"; +"purchase.uncredited.alert.button.recover" = "回復帳戶"; + +"purchase.trials.intro" = "開始 7 天免費試用"; +"purchase.trials.price.after" = "然後 %@"; +"purchase.trials.money.back" = "30 天退款保證"; +"purchase.trials.1year.protection" = "1 年隱私權和身分保護"; +"purchase.trials.anonymous" = "匿名瀏覽並隱藏 IP。"; +"purchase.trials.devices" = "同時支援 10 台裝置"; +"purchase.trials.devices.description" = "同時為最多 10 台裝置提供保護。"; +"purchase.trials.region" = "可輕鬆連線到任何地區"; +"purchase.trials.servers" = "32 個國家超過 3300 台伺服器"; +"purchase.trials.start" = "開始訂閱"; +"purchase.trials.all.plans" = "檢視所有可用方案"; + +"purchase.subscribe.now" = "馬上訂閱"; + +// WALKTHROUGH + +"walkthrough.action.next" = "下一步"; +"walkthrough.action.done" = "完成"; +"walkthrough.action.skip" = "跳過"; + +"walkthrough.page.1.title" = "同時支援 10 台裝置"; +"walkthrough.page.1.description" = "同時為多達 10 台裝置提供保護"; +"walkthrough.page.2.title" = "輕易就能連線到任何地區"; +"walkthrough.page.2.description" = "我們的伺服器遍佈全球,能為您提供全面保護。"; +"walkthrough.page.3.title" = "讓自己免受廣告滋擾"; +"walkthrough.page.3.description" = "只要啟用我們的內容阻擋器,使用 Safari 瀏覽器時就再也不會看到廣告。"; + +"share.data.buttons.accept" = "接受"; +"share.data.buttons.noThanks" = "不了,謝謝"; +"share.data.buttons.readMore" = "閱讀更多內容"; +"share.data.text.title" = "請協助我們改善服務"; +"share.data.text.description" = "為了確保服務的連線品質,您可以匿名與我們分享您的連線統計資料。這些報告不會包含任何個人識別資訊。"; +"share.data.text.footer" = "您隨時都可以在設定中控制。"; + +"share.data.readMore.text.description" = "This minimal information assists us in identifying and fixing potential connection issues. Note that sharing this information requires consent and manual activation as it is turned off by default. + +We will collect information about the following events: + + - Connection Attempt + - Connection Canceled + - Connection Established + +For all of these events, we will collect the following information: + - Platform + - App version + - App type (pre-release or not) + - Protocol used + - Connection source (manual or using automation) + - Time To Connect (time between connecting and connected state) + +All events will contain a unique ID, which is randomly generated. This ID is not associated with your user account. This unique ID is re-generated daily for privacy purposes. + +You will always be in control. You can see what data we’ve collected from Settings, and you can turn it off at any time."; diff --git a/Resources/Resources/iOS/zh-Hant.lproj/Welcome.strings b/Resources/Resources/iOS/zh-Hant.lproj/Welcome.strings new file mode 100644 index 000000000..b4c846e04 --- /dev/null +++ b/Resources/Resources/iOS/zh-Hant.lproj/Welcome.strings @@ -0,0 +1,88 @@ +/* + Welcome.strings + PIALibrary + + Created by Davide De Rosa on 12/7/17. + Copyright © 2017 London Trust Media. All rights reserved. +*/ + +"login.title" = "登入帳戶"; +"login.username.placeholder" = "使用者名稱(p1234567)"; +"login.password.placeholder" = "密碼"; +"login.submit" = "登入"; +"login.restore.button" = "收不到帳戶資料?"; +"login.error.title" = "登入"; +"login.error.validation" = "您必須輸入使用者名稱及密碼。"; +"login.error.unauthorized" = "您的使用者名稱或密碼不正確。"; +"login.error.throttled" = "Too many failed login attempts with this username. Please try again after %@ second(s)."; +"login.receipt.button" = "使用購買收據登入"; +"login.magic.link.title" = "使用神奇的電子郵件連結登入"; +"login.magic.link.response" = "請確認電子信箱是否已收到登入連結。"; +"login.magic.link.send" = "傳送連結"; +"login.magic.link.invalid.email" = "無效的電子郵件。請重試。"; + +"purchase.title" = "選擇 VPN 方案"; +"purchase.subtitle" = "30 天退款保證"; +"purchase.email.placeholder" = "電子郵件地址"; +"purchase.continue" = "繼續"; +"purchase.login.footer" = "已有帳號?"; +"purchase.login.button" = "登入"; +"purchase.error.title" = "購買"; +"purchase.error.validation" = "必須輸入電郵地址。"; +"purchase.error.connectivity.title" = "連線失敗"; +"purchase.error.connectivity.description" = "我們無法連線至 Private Internet Access。這可能是因為您的網路連線狀態不佳,或我們的服務在您的國家遭到封鎖。"; +"purchase.confirm.form.email" = "請輸入您的電子郵件地址"; +"purchase.confirm.plan" = "您正在購買 %@ 方案"; +"purchase.email.why" = "請提供電子郵件以便我們傳送使用者名稱及密碼。"; +"purchase.submit" = "提交"; +"purchase.or" = "或"; + +"upgrade.header" = "歡迎回來!"; +"upgrade.title" = "如果要使用 Private Internet Access,您必須續訂。"; +"upgrade.renew.now" = "立即續訂"; + + + +"redeem.title" = "兌換禮品卡"; +"redeem.subtitle" = "於下方輸入您的電子郵件地址及禮品卡或試用卡並的 %lu 位數 PIN 碼。"; +"redeem.email.placeholder" = "電子郵件地址"; +"redeem.submit" = "提交"; +"redeem.error.title" = "兌換"; +"redeem.error.code" = "代碼必須包含 %lu 個數字。"; +"redeem.error.allfields" = "請輸入您的電子郵件地址及禮品卡 PIN 碼。"; +"redeem.accessibility.back" = "返回"; +"redeem.giftcard.placeholder" = "禮品卡 PIN 碼"; + +"plan.monthly.title" = "月繳"; +"plan.yearly.title" = "年繳"; +"plan.yearly.detail_format" = "每年 %@%@"; +"plan.price_format" = "每月 %@"; +"plan.best_value" = "最佳值"; +"plan.accessibility.per_month" = "/ 月"; + +"restore.title" = "回復未貸記購買項目"; +"restore.subtitle" = "如果您透過此應用程式購買方案後收不到您的憑證,可以透過這裡要求再次傳送。此操作不會收取任何費用。"; +"restore.email.placeholder" = "電子郵件地址"; +"restore.submit" = "確定"; + +"iap.error.message.unavailable" = "Apple 伺服器目前無法使用,請稍後再試。"; +"iap.error.title" = "錯誤"; + +"agreement.trials.title" = "免費試用條款與條件"; +"agreement.trials.message" = "確認購買後,系統將從您的 Apple ID 帳號收取費用。除非您在目前訂閱期間結束前至少 24 小時取消訂閱,否則訂閱將自動續訂。在目前期間結束前 24 小時內,將從您的帳號收取續訂費用。您可在購買後,前往 App Store 的帳號設定管理和取消您的訂閱。\n\n「特定付費訂閱」可能在以您的付費方式收費前,提供免費試用。若您在我們開始以您的付費方式收費前,決定取消「付費訂閱」,請在免費試用結束前至少 24 小時取消訂閱。\n\n只有新使用者才享有免費試用的資格,且我們擁有唯一決定權。若您試圖再次註冊免費試用,我們會立即以「標準訂閱費用」向您收費。\n\n我們保留隨時解除您免費試用的權利。\n\n若您的免費試用有任何未使用的期間,將會在購買訂閱時收回。\n\n若註冊即代表您接受此條款與條件。"; +"agreement.message" = "免費試用 7 天後,除非您在試用期結束前至少 24 小時取消訂閱,否則系統將自動續訂 %@,並在試用期結束前的 24 小時內,從您的 Apple ID 帳號收取續訂費用。購買後,您可以前往 App Store 的帳號設定管理或取消您的訂閱方案。每位用戶只有一次 7 天試用的機會。若您的免費試用有任何未使用的期間,將會在購買訂閱時收回。所有價格已包括適用於當地的營業稅。\n\n若註冊,即代表您已接受 $1 與 $2。"; +"agreement.trials.yearly.plan" = "年"; +"agreement.trials.monthly.plan" = "月"; + +"agreement.message.tos" = "服務條款"; +"agreement.message.privacy" = "隱私權政策"; + +"getstarted.buttons.buyaccount" = "購買帳戶"; + +"gdpr.collect.data.title" = "我們收集的個人資料"; +"gdpr.collect.data.description" = "電子郵件地址用於管理帳戶及防止濫用。"; +"gdpr.usage.data.title" = "我們收集個人資料的用途"; +"gdpr.usage.data.description" = "電子郵件地址僅用於傳送訂閱資訊、付款確認函、客戶通訊及 Private Internet Access 的促銷優惠。"; +"gdpr.accept.button.title" = "同意並繼續"; + +"update.account.email.error" = "無法修改帳戶電子郵件"; diff --git a/Resources/UI/Signup.storyboard b/Resources/UI/Signup.storyboard new file mode 100644 index 000000000..543ebe91d --- /dev/null +++ b/Resources/UI/Signup.storyboard @@ -0,0 +1,1121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/UI/Welcome.storyboard b/Resources/UI/Welcome.storyboard new file mode 100644 index 000000000..0cebb73e1 --- /dev/null +++ b/Resources/UI/Welcome.storyboard @@ -0,0 +1,1321 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/UI/en.lproj/Main.storyboard b/Resources/UI/en.lproj/Main.storyboard index ec71595b5..52056da2e 100644 --- a/Resources/UI/en.lproj/Main.storyboard +++ b/Resources/UI/en.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -14,20 +14,20 @@ - + - + - + - + @@ -43,7 +43,7 @@ - - + @@ -165,10 +165,10 @@ - +