diff --git a/.github/workflows/appcast.yml b/.github/workflows/appcast.yml
index fe8b09e..ce61d3f 100644
--- a/.github/workflows/appcast.yml
+++ b/.github/workflows/appcast.yml
@@ -15,15 +15,15 @@ jobs:
persist-credentials: false
- name: Cache š¦
- uses: actions/cache@v3.0.11
+ uses: actions/cache@v3.3.1
with:
path: AppCast/vendor/bundle
key: ${{ runner.os }}-gems-v1.0-${{ hashFiles('AppCast/Gemfile') }}
restore-keys: |
${{ runner.os }}-gems-
- - name: Ruby ā¦ļø
- uses: actions/setup-ruby@v1.1.3
+ - name: Setup Ruby, JRuby and TruffleRuby
+ uses: ruby/setup-ruby@v1.149.0
with:
ruby-version: '2.7'
diff --git a/README.md b/README.md
index 96107ce..9ce57a1 100644
--- a/README.md
+++ b/README.md
@@ -2,13 +2,17 @@
The easiest way to install and switch between multiple versions of Xcode.
-_If you're looking for a command-line version of Xcodes.app, try [`xcodes`](https://github.com/RobotsAndPencils/xcodes)._
+_If you're looking for a command-line version of Xcodes.app, try [`xcodes`](https://github.com/XcodesOrg/xcodes)._
-
+


+### :tada: Announcment
+
+XcodesApp is now part of the `XcodesOrg` - [read more here](nextstep.md)
+
## Features
- List all available Xcode versions from [Xcode Releases'](https://xcodereleases.com) data or the Apple Developer website.
@@ -21,14 +25,14 @@ _If you're looking for a command-line version of Xcodes.app, try [`xcodes`](http
## Experiments
-- Thanks to the wonderful work of [https://github.com/saagarjha/unxip](https://github.com/saagarjha/unxip), turn on the experiment to increase your unxipping time by up to 70%! More can be found on his repo, but bugs, high memory may occur if used.
+- Thanks to the wonderful work of [https://github.com/saagarjha/unxip](https://github.com/saagarjha/unxip), turn on the experiment to increase your unxipping time by up to 70%! More can be found on his repo, but bugs, high memory may occur if used.
-
-
+
+
## Localization
-Xcodes supports localization in several languages.
+Xcodes supports localization in several languages.
The following languages are supported because of the following community users!
@@ -36,37 +40,36 @@ The following languages are supported because of the following community users!
|-|-|-|-|
|French š«š· |[@dompepin](https://github.com/dompepin)|Italian š®š¹ |[gualtierofrigerio](https://github.com/gualtierofrigerio)|
|Spanish šŖšøš² |[@cesartru88](https://github.com/cesartru88)|Korean š°š· |[@ryan-son](https://github.com/ryan-son)|
-|Russian š·šŗ |[@alexmazlov](https://github.com/alexmazlov)|Turkish š¹š· |[@egrimo](https://github.com/egrimo)|
+|Russian š·šŗ |[@alexmazlov](https://github.com/alexmazlov)|Turkish š¹š· |[@egesucu](https://github.com/egesucu)|
|Hindi š®š³ |[@KGurpreet](https://github.com/KGurpreet)|Chinese-Simplified šØš³|[@megabitsenmzq](https://github.com/megabitsenmzq)|
|Finnish š«š® |[@marcusziade](https://github.com/marcusziade)|Chinese-Traditional š¹š¼|[@itszero](https://github.com/itszero)|
|Ukranian šŗš¦ |[@gelosi](https://github.com/gelosi)|Japanese šÆšµ|[@tatsuz0u](https://github.com/tatsuz0u)|
|German š©šŖ|[@drct](https://github.com/drct)|Dutch š³š±|[@jfversluis](https://github/com/jfversluis)|
-|Brazilian Portuguese š§š·|[@brunomunizaf](https://github.com/brunomunizaf)|Catalan|[@ferranabello](https://github.com/ferranabello)||
+|Brazilian Portuguese š§š·|[@brunomunizaf](https://github.com/brunomunizaf)|Polish šµš±|[@jakex7](https://github.com/jakex7)|
+|Catalan|[@ferranabello](https://github.com/ferranabello)|
-Want to add more languages? Simply create a PR with the updated strings file.
+Want to add more languages? Simply create a PR with the updated strings file.
## Installation
Xcodes.app runs on macOS Big Sur 11.0 or later.
-### Homebrew Cask
+### Install with Homebrew
+
+Developer ID-signed and notarized release builds are available on Homebrew. These don't require Xcode to already be installed in order to use.
```sh
brew install --cask xcodes
-
-# These are Developer ID-signed and notarized release builds and don't require Xcode to already be installed in order to use.
```
-### Download a release
+### Manually install
-1. Download the latest version [here](https://github.com/RobotsAndPencils/XcodesApp/releases/latest) using the **Xcodes.zip** asset. These are Developer ID-signed and notarized release builds and don't require Xcode to already be installed in order to use.
+1. Download the latest version [here](https://github.com/XcodesOrg/XcodesApp/releases/latest) using the **Xcodes.zip** asset. These are Developer ID-signed and notarized release builds and don't require Xcode to already be installed in order to use.
2. Move the unzipped `Xcodes.app` to your `/Applications` directory
## Development
You'll need macOS 12 Big Sur and Xcode 13 in order to build and run Xcodes.app.
-If you aren't a Robots and Pencils employee you'll need to change the CODE_SIGNING_SUBJECT_ORGANIZATIONAL_UNIT build setting to your Apple Developer team ID in order for code signing validation to succeed between the main app and the privileged helper.
-
`Unxip` and `aria2` must be compiled as a universal binary
```
# compile for Intel
@@ -77,7 +80,7 @@ If you aren't a Robots and Pencils employee you'll need to change the CODE_SIGNI
# combine for universal binary
lipo -create -output unxip unxip_intel unxip_m1
# check it
- lipo -archs unxip
+ lipo -archs unxip
```
Notable design decisions are recorded in [DECISIONS.md](./DECISIONS.md). The Apple authentication flow is described in [Apple.paw](./Apple.paw), which will allow you to play with the API endpoints that are involved using the [Paw](https://paw.cloud) app.
@@ -133,7 +136,7 @@ pushd Product
../scripts/sign_update Xcodes.zip
popd
-# Go to https://github.com/RobotsAndPencils/XcodesApp/releases
+# Go to https://github.com/XcodesOrg/XcodesApp/releases
# If there are uncategorized PRs, add the appropriate label and run the Release Drafter action manually
# Edit the latest draft release
# Set its tag to the tag you just pushed
@@ -152,9 +155,4 @@ popd
[Matt Kiazyk](https://github.com/mattkiazyk) - [Twitter](https://www.twitter.com/mattkiazyk)
-
-
-
-Made with ā¤ļø by [Robots & Pencils](http://www.robotsandpencils.com)
-
-[Twitter](https://twitter.com/xcodesApp) | [GitHub](https://github.com/robotsandpencils)
+[Twitter](https://twitter.com/xcodesApp) | [GitHub](https://github.com/xcodesOrg)
diff --git a/Xcodes.xcodeproj/project.pbxproj b/Xcodes.xcodeproj/project.pbxproj
index a298a5f..8f15b47 100644
--- a/Xcodes.xcodeproj/project.pbxproj
+++ b/Xcodes.xcodeproj/project.pbxproj
@@ -172,6 +172,7 @@
/* Begin PBXFileReference section */
15FAD1652811D15600B63259 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/Localizable.strings; sourceTree = ""; };
+ 23703D6E29EBF63500DFA346 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; };
25E2FA26284769A00014A318 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; };
327DF109286ABE6B00D694D5 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Localizable.strings"; sourceTree = ""; };
36741BFC291E4FDB00A85AAE /* DownloadPreferencePane.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownloadPreferencePane.swift; sourceTree = ""; };
@@ -736,6 +737,7 @@
ca,
"pt-BR",
nl,
+ pl,
);
mainGroup = CAD2E7952449574E00113D76;
packageReferences = (
@@ -955,6 +957,7 @@
5C3927ED28E4B486007B5119 /* ca */,
327DF109286ABE6B00D694D5 /* pt-BR */,
E2AFDCCA28F024D000864ADD /* nl */,
+ 23703D6E29EBF63500DFA346 /* pl */,
);
name = Localizable.strings;
sourceTree = "";
@@ -1033,7 +1036,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 17;
+ CURRENT_PROJECT_VERSION = 18;
DEVELOPMENT_ASSET_PATHS = "\"Xcodes/Preview Content\"";
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = NO;
@@ -1043,7 +1046,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
- MARKETING_VERSION = 1.9.0;
+ MARKETING_VERSION = 1.10.0;
PRODUCT_BUNDLE_IDENTIFIER = com.robotsandpencils.XcodesApp;
PRODUCT_NAME = Xcodes;
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -1274,7 +1277,7 @@
CODE_SIGN_ENTITLEMENTS = Xcodes/Resources/Xcodes.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 17;
+ CURRENT_PROJECT_VERSION = 18;
DEVELOPMENT_ASSET_PATHS = "\"Xcodes/Preview Content\"";
DEVELOPMENT_TEAM = PBH8V487HB;
ENABLE_HARDENED_RUNTIME = YES;
@@ -1284,7 +1287,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
- MARKETING_VERSION = 1.9.0;
+ MARKETING_VERSION = 1.10.0;
PRODUCT_BUNDLE_IDENTIFIER = com.robotsandpencils.XcodesApp;
PRODUCT_NAME = Xcodes;
SWIFT_VERSION = 5.0;
@@ -1298,7 +1301,7 @@
CODE_SIGN_ENTITLEMENTS = Xcodes/Resources/Xcodes.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 17;
+ CURRENT_PROJECT_VERSION = 18;
DEVELOPMENT_ASSET_PATHS = "\"Xcodes/Preview Content\"";
DEVELOPMENT_TEAM = PBH8V487HB;
ENABLE_HARDENED_RUNTIME = YES;
@@ -1308,7 +1311,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
- MARKETING_VERSION = 1.9.0;
+ MARKETING_VERSION = 1.10.0;
PRODUCT_BUNDLE_IDENTIFIER = com.robotsandpencils.XcodesApp;
PRODUCT_NAME = Xcodes;
SWIFT_VERSION = 5.0;
diff --git a/Xcodes/AppleAPI/Sources/AppleAPI/Client.swift b/Xcodes/AppleAPI/Sources/AppleAPI/Client.swift
index c8e2810..6f33a4a 100644
--- a/Xcodes/AppleAPI/Sources/AppleAPI/Client.swift
+++ b/Xcodes/AppleAPI/Sources/AppleAPI/Client.swift
@@ -14,12 +14,22 @@ public class Client {
return Current.network.dataTask(with: URLRequest.itcServiceKey)
.map(\.data)
.decode(type: ServiceKeyResponse.self, decoder: JSONDecoder())
- .flatMap { serviceKeyResponse -> AnyPublisher in
+ .flatMap { serviceKeyResponse -> AnyPublisher<(String, String), Swift.Error> in
serviceKey = serviceKeyResponse.authServiceKey
- return Current.network.dataTask(with: URLRequest.signIn(serviceKey: serviceKey, accountName: accountName, password: password))
- .mapError { $0 as Swift.Error }
+
+ // Fixes issue https://github.com/RobotsAndPencils/XcodesApp/issues/360
+ // On 2023-02-23, Apple added a custom implementation of hashcash to their auth flow
+ // Without this addition, Apple ID's would get set to locked
+ return self.loadHashcash(accountName: accountName, serviceKey: serviceKey)
+ .map { return (serviceKey, $0)}
.eraseToAnyPublisher()
}
+ .flatMap { (serviceKey, hashcash) -> AnyPublisher in
+
+ return Current.network.dataTask(with: URLRequest.signIn(serviceKey: serviceKey, accountName: accountName, password: password, hashcash: hashcash))
+ .mapError { $0 as Swift.Error }
+ .eraseToAnyPublisher()
+ }
.flatMap { result -> AnyPublisher in
let (data, response) = result
return Just(data)
@@ -56,6 +66,44 @@ public class Client {
.mapError { $0 as Swift.Error }
.eraseToAnyPublisher()
}
+
+ func loadHashcash(accountName: String, serviceKey: String) -> AnyPublisher {
+
+ Result {
+ try URLRequest.federate(account: accountName, serviceKey: serviceKey)
+ }
+ .publisher
+ .flatMap { request in
+ Current.network.dataTask(with: request)
+ .mapError { $0 as Error }
+ .tryMap { (data, response) throws -> (String) in
+ guard let urlResponse = response as? HTTPURLResponse else {
+ throw AuthenticationError.invalidSession
+ }
+ switch urlResponse.statusCode {
+ case 200..<300:
+
+ let httpResponse = response as! HTTPURLResponse
+ guard let bitsString = httpResponse.allHeaderFields["X-Apple-HC-Bits"] as? String, let bits = UInt(bitsString) else {
+ throw AuthenticationError.invalidHashcash
+ }
+ guard let challenge = httpResponse.allHeaderFields["X-Apple-HC-Challenge"] as? String else {
+ throw AuthenticationError.invalidHashcash
+ }
+ guard let hashcash = Hashcash().mint(resource: challenge, bits: bits) else {
+ throw AuthenticationError.invalidHashcash
+ }
+ return (hashcash)
+ case 400, 401:
+ throw AuthenticationError.invalidHashcash
+ case let code:
+ throw AuthenticationError.badStatusCode(statusCode: code, data: data, response: urlResponse)
+ }
+ }
+ }
+ .eraseToAnyPublisher()
+
+ }
func handleTwoStepOrFactor(data: Data, response: URLResponse, serviceKey: String) -> AnyPublisher {
let httpResponse = response as! HTTPURLResponse
@@ -190,6 +238,7 @@ public enum AuthenticationState: Equatable {
public enum AuthenticationError: Swift.Error, LocalizedError, Equatable {
case invalidSession
+ case invalidHashcash
case invalidUsernameOrPassword(username: String)
case incorrectSecurityCode
case unexpectedSignInResponse(statusCode: Int, message: String?)
@@ -206,6 +255,8 @@ public enum AuthenticationError: Swift.Error, LocalizedError, Equatable {
switch self {
case .invalidSession:
return "Your authentication session is invalid. Try signing in again."
+ case .invalidHashcash:
+ return "Could not create a hashcash for the session."
case .invalidUsernameOrPassword:
return "Invalid username and password combination."
case .incorrectSecurityCode:
diff --git a/Xcodes/AppleAPI/Sources/AppleAPI/Hashcash.swift b/Xcodes/AppleAPI/Sources/AppleAPI/Hashcash.swift
new file mode 100644
index 0000000..135f1ea
--- /dev/null
+++ b/Xcodes/AppleAPI/Sources/AppleAPI/Hashcash.swift
@@ -0,0 +1,96 @@
+//
+// Hashcash.swift
+//
+//
+// Created by Matt Kiazyk on 2023-02-23.
+//
+
+import Foundation
+import CryptoKit
+import CommonCrypto
+
+/*
+# This App Store Connect hashcash spec was generously donated by...
+ #
+ # __ _
+ # __ _ _ __ _ __ / _|(_) __ _ _ _ _ __ ___ ___
+ # / _` || '_ \ | '_ \ | |_ | | / _` || | | || '__|/ _ \/ __|
+ # | (_| || |_) || |_) || _|| || (_| || |_| || | | __/\__ \
+ # \__,_|| .__/ | .__/ |_| |_| \__, | \__,_||_| \___||___/
+ # |_| |_| |___/
+ #
+ #
+*/
+public struct Hashcash {
+ /// A function to returned a minted hash, using a bit and resource string
+ ///
+ /**
+ X-APPLE-HC: 1:11:20230223170600:4d74fb15eb23f465f1f6fcbf534e5877::6373
+ ^ ^ ^ ^ ^
+ | | | | +-- Counter
+ | | | +-- Resource
+ | | +-- Date YYMMDD[hhmm[ss]]
+ | +-- Bits (number of leading zeros)
+ +-- Version
+
+ We can't use an off-the-shelf Hashcash because Apple's implementation is not quite the same as the spec/convention.
+ 1. The spec calls for a nonce called "Rand" to be inserted between the Ext and Counter. They don't do that at all.
+ 2. The Counter conventionally encoded as base-64 but Apple just uses the decimal number's string representation.
+
+ Iterate from Counter=0 to Counter=N finding an N that makes the SHA1(X-APPLE-HC) lead with Bits leading zero bits
+ We get the "Resource" from the X-Apple-HC-Challenge header and Bits from X-Apple-HC-Bits
+ */
+ /// - Parameters:
+ /// - resource: a string to be used for minting
+ /// - bits: grabbed from `X-Apple-HC-Bits` header
+ /// - date: Default uses Date() otherwise used for testing to check.
+ /// - Returns: A String hash to use in `X-Apple-HC` header on /signin
+ public func mint(resource: String,
+ bits: UInt = 10,
+ date: String? = nil) -> String? {
+
+ let ver = "1"
+
+ var ts: String
+ if let date = date {
+ ts = date
+ } else {
+ let formatter = DateFormatter()
+ formatter.dateFormat = "yyMMddHHmmss"
+ ts = formatter.string(from: Date())
+ }
+
+ let challenge = "\(ver):\(bits):\(ts):\(resource):"
+
+ var counter = 0
+
+ while true {
+ guard let digest = ("\(challenge):\(counter)").sha1 else {
+ print("ERROR: Can't generate SHA1 digest")
+ return nil
+ }
+
+ if digest == bits {
+ return "\(challenge):\(counter)"
+ }
+ counter += 1
+ }
+ }
+}
+
+extension String {
+ var sha1: Int? {
+
+ let data = Data(self.utf8)
+ var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))
+ data.withUnsafeBytes {
+ _ = CC_SHA1($0.baseAddress, CC_LONG(data.count), &digest)
+ }
+ let bigEndianValue = digest.withUnsafeBufferPointer {
+ ($0.baseAddress!.withMemoryRebound(to: UInt32.self, capacity: 1) { $0 })
+ }.pointee
+ let value = UInt32(bigEndian: bigEndianValue)
+ return value.leadingZeroBitCount
+ }
+}
+
diff --git a/Xcodes/AppleAPI/Sources/AppleAPI/URLRequest+Apple.swift b/Xcodes/AppleAPI/Sources/AppleAPI/URLRequest+Apple.swift
index 01b98fb..d052d63 100644
--- a/Xcodes/AppleAPI/Sources/AppleAPI/URLRequest+Apple.swift
+++ b/Xcodes/AppleAPI/Sources/AppleAPI/URLRequest+Apple.swift
@@ -7,6 +7,7 @@ public extension URL {
static let requestSecurityCode = URL(string: "https://idmsa.apple.com/appleauth/auth/verify/phone")!
static func submitSecurityCode(_ code: SecurityCode) -> URL { URL(string: "https://idmsa.apple.com/appleauth/auth/verify/\(code.urlPathComponent)/securitycode")! }
static let trust = URL(string: "https://idmsa.apple.com/appleauth/auth/2sv/trust")!
+ static let federate = URL(string: "https://idmsa.apple.com/appleauth/auth/federate")!
static let olympusSession = URL(string: "https://appstoreconnect.apple.com/olympus/v1/session")!
}
@@ -15,7 +16,7 @@ public extension URLRequest {
return URLRequest(url: .itcServiceKey)
}
- static func signIn(serviceKey: String, accountName: String, password: String) -> URLRequest {
+ static func signIn(serviceKey: String, accountName: String, password: String, hashcash: String) -> URLRequest {
struct Body: Encodable {
let accountName: String
let password: String
@@ -27,6 +28,7 @@ public extension URLRequest {
request.allHTTPHeaderFields?["Content-Type"] = "application/json"
request.allHTTPHeaderFields?["X-Requested-With"] = "XMLHttpRequest"
request.allHTTPHeaderFields?["X-Apple-Widget-Key"] = serviceKey
+ request.allHTTPHeaderFields?["X-Apple-HC"] = hashcash
request.allHTTPHeaderFields?["Accept"] = "application/json, text/javascript"
request.httpMethod = "POST"
request.httpBody = try! JSONEncoder().encode(Body(accountName: accountName, password: password))
@@ -117,4 +119,21 @@ public extension URLRequest {
static var olympusSession: URLRequest {
return URLRequest(url: .olympusSession)
}
+
+ static func federate(account: String, serviceKey: String) throws -> URLRequest {
+ struct FederateRequest: Encodable {
+ let accountName: String
+ let rememberMe: Bool
+ }
+ var request = URLRequest(url: .signIn)
+ request.allHTTPHeaderFields?["Accept"] = "application/json"
+ request.allHTTPHeaderFields?["Content-Type"] = "application/json"
+ request.httpMethod = "GET"
+
+// let encoder = JSONEncoder()
+// encoder.outputFormatting = .withoutEscapingSlashes
+// request.httpBody = try encoder.encode(FederateRequest(accountName: account, rememberMe: true))
+
+ return request
+ }
}
diff --git a/Xcodes/AppleAPI/Tests/AppleAPITests/AppleAPITests.swift b/Xcodes/AppleAPI/Tests/AppleAPITests/AppleAPITests.swift
index 283dbc6..ecb93e7 100644
--- a/Xcodes/AppleAPI/Tests/AppleAPITests/AppleAPITests.swift
+++ b/Xcodes/AppleAPI/Tests/AppleAPITests/AppleAPITests.swift
@@ -2,14 +2,26 @@ import XCTest
@testable import AppleAPI
final class AppleAPITests: XCTestCase {
- func testExample() {
- // This is an example of a functional test case.
- // Use XCTAssert and related functions to verify your tests produce the correct
- // results.
- XCTAssertEqual(AppleAPI().text, "Hello, World!")
+
+ func testValidHashCashMint() {
+ let bits: UInt = 11
+ let resource = "4d74fb15eb23f465f1f6fcbf534e5877"
+ let testDate = "20230223170600"
+
+ let stamp = Hashcash().mint(resource: resource, bits: bits, date: testDate)
+ XCTAssertEqual(stamp, "1:11:20230223170600:4d74fb15eb23f465f1f6fcbf534e5877::6373")
+ }
+ func testValidHashCashMint2() {
+ let bits: UInt = 10
+ let resource = "bb63edf88d2f9c39f23eb4d6f0281158"
+ let testDate = "20230224001754"
+
+ let stamp = Hashcash().mint(resource: resource, bits: bits, date: testDate)
+ XCTAssertEqual(stamp, "1:10:20230224001754:bb63edf88d2f9c39f23eb4d6f0281158::866")
}
static var allTests = [
- ("testExample", testExample),
+ ("testValidHashCashMint", testValidHashCashMint),
+ ("testValidHashCashMint2", testValidHashCashMint2),
]
}
diff --git a/Xcodes/Backend/DateFormatter+.swift b/Xcodes/Backend/DateFormatter+.swift
index 5aed8ab..a0073de 100644
--- a/Xcodes/Backend/DateFormatter+.swift
+++ b/Xcodes/Backend/DateFormatter+.swift
@@ -6,6 +6,7 @@ extension DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "MM/dd/yy HH:mm"
formatter.locale = Locale(identifier: "en_US_POSIX")
+ formatter.calendar = .init(identifier: .iso8601)
return formatter
}()
diff --git a/Xcodes/Frontend/Preferences/UpdatesPreferencePane.swift b/Xcodes/Frontend/Preferences/UpdatesPreferencePane.swift
index 282b806..349d9be 100644
--- a/Xcodes/Frontend/Preferences/UpdatesPreferencePane.swift
+++ b/Xcodes/Frontend/Preferences/UpdatesPreferencePane.swift
@@ -117,8 +117,8 @@ class ObservableUpdater: ObservableObject {
}
extension URL {
- static let appcast = URL(string: "https://robotsandpencils.github.io/XcodesApp/appcast.xml")!
- static let prereleaseAppcast = URL(string: "https://robotsandpencils.github.io/XcodesApp/appcast_pre.xml")!
+ static let appcast = URL(string: "https://www.xcodes.app/appcast.xml")!
+ static let prereleaseAppcast = URL(string: "https://www.xcodes.app/appcast_pre.xml")!
}
struct UpdatesPreferencePane_Previews: PreviewProvider {
diff --git a/Xcodes/Frontend/XcodeList/BottomStatusBar.swift b/Xcodes/Frontend/XcodeList/BottomStatusBar.swift
index ed74fe6..cd38c3b 100644
--- a/Xcodes/Frontend/XcodeList/BottomStatusBar.swift
+++ b/Xcodes/Frontend/XcodeList/BottomStatusBar.swift
@@ -9,27 +9,27 @@
import Foundation
import SwiftUI
-
struct BottomStatusModifier: ViewModifier {
@EnvironmentObject var appState: AppState
func body(content: Content) -> some View {
- content
VStack(spacing: 0) {
- Divider()
- HStack {
- Text(appState.bottomStatusBarMessage)
- .font(.subheadline)
- Spacer()
- Text(Bundle.main.shortVersion!)
- .font(.subheadline)
+ content
+ VStack(spacing: 0) {
+ Divider()
+ HStack {
+ Text(appState.bottomStatusBarMessage)
+ .font(.subheadline)
+ Spacer()
+ Text(Bundle.main.shortVersion!)
+ .font(.subheadline)
+ }
+ .frame(maxWidth: .infinity, maxHeight: 30, alignment: .leading)
+ .padding([.leading, .trailing], 10)
}
.frame(maxWidth: .infinity, maxHeight: 30, alignment: .leading)
- .padding([.leading, .trailing], 10)
}
- .frame(maxWidth: .infinity, maxHeight: 30, alignment: .leading)
}
-
}
extension View {
diff --git a/Xcodes/Frontend/XcodeList/MainToolbar.swift b/Xcodes/Frontend/XcodeList/MainToolbar.swift
index dcff73a..69a48f2 100644
--- a/Xcodes/Frontend/XcodeList/MainToolbar.swift
+++ b/Xcodes/Frontend/XcodeList/MainToolbar.swift
@@ -13,12 +13,12 @@ struct MainToolbarModifier: ViewModifier {
}
private var toolbar: some ToolbarContent {
- ToolbarItemGroup(placement: .status) {
+ ToolbarItemGroup {
Button(action: { appState.presentedSheet = .signIn }, label: {
Label("Login", systemImage: "person.circle")
})
.help("LoginDescription")
-
+
ProgressButton(
isInProgress: appState.isUpdating,
action: appState.update
@@ -85,7 +85,7 @@ struct MainToolbarModifier: ViewModifier {
}
.keyboardShortcut(KeyboardShortcut("i", modifiers: [.command, .option]))
.help("InfoDescription")
-
+
Button(action: {
if #available(macOS 13, *) {
NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil)
diff --git a/Xcodes/Resources/Info.plist b/Xcodes/Resources/Info.plist
index 58e8717..49fe676 100644
--- a/Xcodes/Resources/Info.plist
+++ b/Xcodes/Resources/Info.plist
@@ -25,7 +25,7 @@
LSMinimumSystemVersion
$(MACOSX_DEPLOYMENT_TARGET)
NSHumanReadableCopyright
- Copyright Ā© 2022 Robots and Pencils.
+ Copyright Ā© 2023 Robots and Pencils.
NSPrincipalClass
NSApplication
NSSupportsAutomaticTermination
@@ -38,7 +38,7 @@
identifier "com.robotsandpencils.XcodesApp.Helper" and info [CFBundleShortVersionString] >= "1.0.0" and anchor apple generic and certificate leaf[subject.OU] = "$(CODE_SIGNING_SUBJECT_ORGANIZATIONAL_UNIT)"
SUFeedURL
- https://robotsandpencils.github.io/XcodesApp/appcast.xml
+ https://www.xcodes.app/appcast.xml
SUPublicEDKey
SEcz0vgUSeBTOoAXYe+64zea95G6lIf5NgzFs3InYJQ=
diff --git a/Xcodes/Resources/ja.lproj/Localizable.strings b/Xcodes/Resources/ja.lproj/Localizable.strings
index 33cb1c9..90aa86f 100644
--- a/Xcodes/Resources/ja.lproj/Localizable.strings
+++ b/Xcodes/Resources/ja.lproj/Localizable.strings
@@ -86,14 +86,25 @@
"LocalCachePathDescription" = "XcodesćÆćå©ēØåÆč½ćŖXcodeć®ćć¼ćøć§ć³ććć£ćć·ć„ććę°ćććć¼ćøć§ć³ććć£ć¬ćÆććŖć«äøęēć«ćć¦ć³ćć¼ććć¾ćć";
"Change" = "å¤ę“";
"Active/Select" = "ć¢ćÆćć£ć";
+"InstallDirectory" = "ć¤ć³ć¹ćć¼ć«å
";
+"InstallPathDescription" = "XcodesćÆ1ć¤ć®ćć£ć¬ćÆććŖćę¤ē“¢ććććć«ć¤ć³ć¹ćć¼ć«ćć¾ććććć©ć«ć (ęØå„Ø) 㯠/Applications ć§ććXcodeć®ę ¼ē“å “ęćå¤ę“ćććØćä»ć®ć¢ććŖć±ć¼ć·ć§ć³ććµć¼ćć¹ćåä½ććŖććŖćåÆč½ę§ćććć¾ćć";
+
+"OnSelectDoNothing" = "ååćXcode-X.X.X.appć®ć¾ć¾ē¶ęćć";
+"OnSelectDoNothingDescription" = "éøęęććć¼ćøć§ć³ä»ćć®ååćē¶ęćć¾ććä¾) Xcode-13.4.1.app";
"AutomaticallyCreateSymbolicLink" = "Xcode.appćøć®ć·ć³ććŖććÆćŖć³ćÆć®čŖåēę";
"AutomaticallyCreateSymbolicLinkDescription" = "Xcodeć®ćć¼ćøć§ć³ćć¢ćÆćć£ćć«ććęćć¤ć³ć¹ćć¼ć«å
ć§Xcode.appć®ć·ć³ććŖććÆćŖć³ćÆć®ä½ęć試ćæć¾ćć";
+"OnSelectRenameXcode" = "ååćåøøć«Xcode.appć«å¤ę“ćć";
+"OnSelectRenameXcodeDescription" = "éøęęćčŖåēć«ć¢ćÆćć£ććŖXcodećXcode.appć«ć仄åć®Xcode.appććć¼ćøć§ć³ä»ćć®ååć«å¤ę“ćć¾ćć";
+
"PrivilegedHelper" = "権éć®ćććć«ćć¼";
"PrivilegedHelperDescription" = "XcodesćÆćrootćØćć¦ćæć¹ćÆćå®č”ććććć«ćå„ć®ęØ©éć®ćććć«ćć¼ć使ēØćć¾ććć¤ć³ć¹ćć¼ć«å¾ć®ęé ć xcode-select ć«ćć Xcode ć®ćć¼ćøć§ć³åćęæććŖć©ćć³ćć³ćć©ć¤ć³ć§ sudo ćåæ
č¦ćØćććć®ć§ćć\n\nć¤ć³ć¹ćć¼ć«ć«ćÆćmacOS ć¢ć«ć¦ć³ćć®ćć¹ćÆć¼ćć®å
„åćåæ
č¦ć§ćć";
"HelperInstalled" = "ć¤ć³ć¹ćć¼ć«ęøćæ";
"HelperNotInstalled" = "ęŖć¤ć³ć¹ćć¼ć«";
"InstallHelper" = "ćć«ćć¼ć®ć¤ć³ć¹ćć¼ć«";
+"ShowOpenInRosetta" = "Rosettać§éććŖćć·ć§ć³ć蔨示ćć";
+"ShowOpenInRosettaDescription" = "Rosettać§éććŖćć·ć§ć³ćÆ \"éć\" ę©č½ćå©ēØć§ććå “ęć«č”Øē¤ŗććć¾ćć注ę: ćććÆApple Siliconćć·ć³ć«ć®ćæč”Øē¤ŗććć¾ćć";
+
// Experiment Preference Pane
"Experiments" = "試éØēćŖę©č½";
"FasterUnxip" = "é«éćŖ Unxip";
@@ -152,6 +163,7 @@
"Alert.Uninstall.Title" = "Xcode %@ ćć¢ć³ć¤ć³ć¹ćć¼ć«ćć¦ćććććć§ććļ¼";
"Alert.Uninstall.Message" = "ć“ćē®±ć«ē§»åććć¾ćććć“ćē®±ćčŖåēć«ē©ŗć«ććććØćÆććć¾ććć";
"Alert.Uninstall.Error.Title" = "Xcode ćć¢ć³ć¤ć³ć¹ćć¼ć«ć§ćć¾ććć§ćć";
+"Alert.Uninstall.Error.Message.FileNotFound" = "ćć”ć¤ć« \"%@\" ćč¦ć¤ććć¾ććć§ććć";
// Cancel Install
"Alert.CancelInstall.Title" = "Xcode %@ ć®ć¤ć³ć¹ćć¼ć«ćäøę¢ćć¦ćććććć§ććļ¼";
@@ -221,3 +233,6 @@
// Notifications
"Notification.NewXcodeVersion.Title" = "ę°ććXcodeć®ćć¼ćøć§ć³";
"Notification.NewXcodeVersion.Body" = "ę°ćććć¼ćøć§ć³ććć¦ć³ćć¼ćć§ćć¾ćć";
+
+// WWDC
+"WWDC.Message" = "šØš»āš»š©š¼āš» Happy WWDC %@! šØš½āš»š§š»āš»";
diff --git a/Xcodes/Resources/pl.lproj/Localizable.strings b/Xcodes/Resources/pl.lproj/Localizable.strings
new file mode 100644
index 0000000..c505451
--- /dev/null
+++ b/Xcodes/Resources/pl.lproj/Localizable.strings
@@ -0,0 +1,239 @@
+// Menu
+"Menu.About" = "O Xcodes";
+"Menu.CheckForUpdates" = "SprawdÅŗ aktualizacje...";
+"Menu.Acknowledgements" = "PodziÄkowania Xcodes";
+"Menu.GitHubRepo" = "Repozytorium Xcodes na GitHubie";
+"Menu.ReportABug" = "ZgÅoÅ bÅÄ
d";
+"Menu.RequestNewFeature" = "PoproÅ o nowÄ
funkcjÄ";
+
+// Common
+"Install" = "Zainstaluj";
+"InstallDescription" = "Zainstaluj tÄ wersjÄ";
+"RevealInFinder" = "Pokaż w Finderze";
+"Active" = "Aktywny";
+"MakeActive" = "Ustaw jako aktywny";
+"Open" = "Otwórz";
+"OpenDescription" = "Otwórz tÄ wersjÄ";
+"CopyPath" = "Kopiuj ÅcieżkÄ";
+"CreateSymLink" = "Utwórz Symlink jako Xcode.app";
+"CreateSymLinkBeta" = "Utwórz Symlink jako Xcode-Beta.app";
+"Uninstall" = "Odinstaluj";
+"Selected" = "Wybrany";
+"Select" = "Wybierz";
+"Cancel" = "Anuluj";
+"Next" = "Dalej";
+"Continue" = "Kontynuuj";
+"Close" = "Zamknij";
+"OK" = "OK";
+
+// Info Pane
+"IdenticalBuilds" = "Takie same wersje";
+"IdenticalBuilds.help" = "Czasami wersja przedpremierowa i wydana sÄ
dokÅadnie takie same. Xcodes automatycznie wyÅwietla te wersje razem.";
+
+"ReleaseDate" = "Data wydania";
+"ReleaseNotes" = "Notatki wydania";
+"ReleaseNotes.help" = "WyÅwietl notatki wydania";
+"CopyReleaseNoteURL" = "Kopiuj adres URL";
+"Compatibility" = "KompatybilnoÅÄ";
+"MacOSRequirement" = "Wymaga systemu macOS %@ lub nowszego";
+"SDKs" = "SDK";
+"Compilers" = "Kompilatory";
+"DownloadSize" = "WielkoÅÄ pobierania";
+"NoXcodeSelected" = "Nie wybrano Xcode";
+
+// Installation Steps
+// When localizing. Items will be replaced in order. ie "Step 1 of 6: Downloading"
+// So if changing order, make sure the positional specficier is retained. ex: "%3$@: Step %1$d of %2$d"
+"InstallationStepDescription" = "Krok %1$d z %2$d: %3$@";
+"DownloadingPercentDescription" = "Pobieranie: %d%% ukoÅczone";
+"StopInstallation" = "Przerwij instalacjÄ";
+"DownloadingError" = "Nie znaleziono informacji o pobieraniu";
+
+// About
+"VersionWithBuild" = "Wersja %@ (%@)";
+"GithubRepo" = "Repozytorium GitHub";
+"Acknowledgements" = "PodziÄkowania";
+"UnxipExperiment" = "Eksperyment Unxip";
+"License" = "Licencja";
+
+// General Preference Pane
+"General" = "Ogólne";
+"AppleID" = "Apple ID";
+"SignIn" = "Zaloguj siÄ";
+"Notifications" = "Powiadomienia";
+
+// Updates Preference Pane
+"Updates" = "Aktualizacje";
+"Versions" = "Wersje";
+"AutomaticInstallNewVersion" = "Automatycznie instaluj nowe wersje Xcode";
+"IncludePreRelease" = "DoÅÄ
cz wersje beta/wstÄpne";
+"AppUpdates" = "Aktualizacje Xcodes.app";
+"CheckForAppUpdates" = "Automatycznie sprawdzaj aktualizacje aplikacji";
+"CheckNow" = "SprawdÅŗ teraz";
+"LastChecked" = "Ostatnio sprawdzono: %@";
+"Never" = "Nigdy";
+
+// Download Preference Pane
+"Downloads" = "Pobieranie";
+"DataSource" = "ŹródÅo danych";
+"DataSourceDescription" = "ŹródÅo danych Apple przeszukuje stronÄ internetowÄ
Apple Developer. Zawsze wyÅwietla najnowsze dostÄpne wydania, ale jest bardziej podatne na problemy.\n\nXcode Releases to nieoficjalna lista wydaÅ Xcode. UdostÄpnia ona dobrze sformatowane dane, zawiera dodatkowe informacje, które nie sÄ
Åatwo dostÄpne w Apple, i jest mniej podatna na problemy, gdy Apple zmienia swojÄ
stronÄ dla deweloperów.";
+"Downloader" = "Pobieranie";
+"DownloaderDescription" = "aria2 używa do pobierania do 16 poÅÄ
czeÅ, co pozwala na pobieranie Xcode 3-5x szybciej niż URLSession. Jest on dostarczany jako plik wykonywalny wraz ze swoim kodem ÅŗródÅowym w ramach Xcodes w celu przestrzegania jego licencji GPLv2.\n\nURLSession to domyÅlne API Apple do tworzenia żÄ
daÅ URL.";
+
+// Advanced Preference Pane
+"Advanced" = "Zaawansowane";
+"LocalCachePath" = "Katalog cache";
+"LocalCachePathDescription" = "Xcodes przechowuje w cache dostÄpne wersje Xcode oraz tymczasowo pobiera nowe pliki do tego katalogu.";
+"Change" = "ZmieÅ";
+"Active/Select" = "Aktywny/wybrany";
+"InstallDirectory" = "Katalog instalacji";
+"InstallPathDescription" = "Xcodes wyszukuje i instaluje w jednym katalogu. DomyÅlnie (i zalecane) jest to /Applications. Wszelkie zmiany w miejscu przechowywania Xcode mogÄ
spowodowaÄ, że inne aplikacje/usÅugi przestanÄ
dziaÅaÄ.";
+
+"OnSelectDoNothing" = "Zachowaj nazwÄ jako Xcode-X.X.X.app";
+"OnSelectDoNothingDescription" = "Po wybraniu, nazwa pozostanie w formacie z numerem wersji, np. Xcode-13.4.1.app";
+"AutomaticallyCreateSymbolicLink" = "Automatycznie twórz symboliczne poÅÄ
czenie do Xcode.app";
+"AutomaticallyCreateSymbolicLinkDescription" = "Przy ustawianiu Xcode jako aktywny/wybrany, próbuj automatycznie stworzyÄ symboliczne poÅÄ
czenie o nazwie Xcode.app w katalogu instalacji.";
+"OnSelectRenameXcode" = "Zawsze zmieniaj nazwÄ na Xcode.app";
+"OnSelectRenameXcodeDescription" = "Po wybraniu, automatycznie zmienia aktywnÄ
wersjÄ Xcode na Xcode.app, a poprzednie Xcode.app zostanie zmienione na nazwÄ wersji.";
+
+"PrivilegedHelper" = "Helper z uprawnieniami";
+"PrivilegedHelperDescription" = "Xcodes używa oddzielnego helpera z uprawnieniami do wykonywania zadaÅ jako root. SÄ
to rzeczy, które wymagaÅyby użycia komendy sudo w wierszu poleceÅ, w tym kroki po instalacji oraz przeÅÄ
czanie wersji Xcode za pomocÄ
xcode-select.\n\nZostaniesz poproszony o podanie hasÅa do swojego konta macOS, aby go zainstalowaÄ.";
+"HelperInstalled" = "Helper jest zainstalowany";
+"HelperNotInstalled" = "Helper nie jest zainstalowany";
+"InstallHelper" = "Zainstaluj helpera";
+
+"ShowOpenInRosetta" = "Pokaż opcjÄ Otwórz w Rosetta";
+"ShowOpenInRosettaDescription" = "Opcja Otwórz w Rosetta bÄdzie wyÅwietlana, gdy dostÄpne sÄ
inne funkcje \"Otwórz\". Uwaga: BÄdzie to dziaÅaÄ tylko na urzÄ
dzeniach z Apple Silicon.";
+
+// Experiment Preference Pane
+"Experiments" = "Eksperymenty";
+"FasterUnxip" = "Szybsze Unxip";
+"UseUnxipExperiment" = "Podczas rozpakowywania, użyj wersji eksperymentalnej";
+"FasterUnxipDescription" = "DziÄki @_saagarjha, wersja eksperymentalna może zwiÄkszyÄ prÄdkoÅÄ rozpakowywania o nawet 70% dla niektórych systemów.\n\nWiÄcej informacji na temat tego, jak to jest osiÄ
gane, można znaleÅŗÄ w repozytorium unxip - https://github.com/saagarjha/unxip";
+
+// Notifications
+"AccessGranted" = "DostÄp przyznany. BÄdziesz otrzymywaÄ powiadomienia z Xcodes.";
+"AccessDenied" = "ā ļø DostÄp zabroniony ā ļø\n\nOtwórz ustawienia powiadomieÅ i wybierz Xcodes, jeÅli chcesz zezwoliÄ na dostÄp.";
+"NotificationSettings" = "Ustawienia powiadomieÅ";
+"EnableNotifications" = "WÅÄ
cz powiadomienia";
+
+// SignIn
+"SignInWithApple" = "Zaloguj siÄ przy użyciu Apple ID.";
+"AppleID" = "AppleID:";
+"Password" = "HasÅo:";
+"Required" = "Wymagane";
+"SignOut" = "Wyloguj siÄ";
+
+// SMS/2FA
+"DigitCodeDescription" = "WprowadÅŗ %d-cyfrowy kod z jednego ze swoich zaufanych urzÄ
dzeÅ:";
+"SendSMS" = "WyÅlij SMS";
+"EnterDigitCodeDescription" = "WprowadÅŗ %d-cyfrowy kod wysÅany do %@: ";
+"SelectTrustedPhone" = "Wybierz zaufany numer telefonu, aby otrzymaÄ %d-cyfrowy kod przez SMS:";
+"NoTrustedPhones" = "Twoje konto nie ma żadnych zaufanych numerów telefonów, ale sÄ
one wymagane do autoryzacji dwuskÅadnikowej.\n\nZobacz https://support.apple.com/HT204915.";
+
+// MainWindow
+"UpdatedAt" = "Zaktualizowano o";
+
+// ToolBar
+"Login" = "Zaloguj siÄ";
+"LoginDescription" = "Otwórz okno logowania";
+"Refresh" = "OdÅwież";
+"RefreshDescription" = "OdÅwież listÄ Xcode";
+"All" = "Wszystkie";
+"Release" = "Stabilne";
+"ReleaseOnly" = "Tylko stabilne";
+"Beta" = "Beta";
+"BetaOnly" = "Tylko beta";
+"Filter" = "Filtr";
+"FilterAvailableDescription" = "Filtruj dostÄpne wersje";
+"FilterInstalledDescription" = "Filtruj zainstalowane wersje";
+"Info" = "Informacje";
+"InfoDescription" = "Pokaż lub ukryj okno informacji";
+"Preferences" = "Ustawienia";
+"PreferencesDescription" = "Otwórz ustawienia";
+"Search" = "Szukaj...";
+"SearchDescription" = "Przeszukaj listÄ";
+
+// List
+"ActiveVersionDescription" = "To jest aktywna wersja";
+"MakeActiveVersionDescription" = "Ustaw jako aktywnÄ
wersjÄ";
+
+// Alerts
+// Uninstall
+"Alert.Uninstall.Title" = "OdinstalowaÄ Xcode %@?";
+"Alert.Uninstall.Message" = "Zostanie przeniesiony do kosza, ale nie zostanie opróżniony.";
+"Alert.Uninstall.Error.Title" = "Nie można odinstalowaÄ Xcode";
+"Alert.Uninstall.Error.Message.FileNotFound" = "Nie znaleziono pliku \"%@\".";
+
+// Cancel Install
+"Alert.CancelInstall.Title" = "Czy na pewno chcesz przerwaÄ instalacjÄ Xcode %@?";
+"Alert.CancelInstall.Message" = "PostÄp zostanie utracony.";
+"Alert.CancelInstall.PrimaryButton" = "Przerwij instalacjÄ";
+
+// Privileged Helper
+"Alert.PrivilegedHelper.Title" = "Helper z uprawnieniami";
+"Alert.PrivilegedHelper.Message" = "Xcodes używa oddzielnego helpera z uprawnieniami, aby wykonywaÄ zadania jako root. SÄ
to rzeczy, które wymagaÅyby sudo w wierszu poleceÅ, w tym kroki po instalacji i przeÅÄ
czanie wersji Xcode z xcode-select.\n\nBÄdziesz proszony o podanie hasÅa do konta macOS, aby go zainstalowaÄ.";
+"Alert.PrivilegedHelper.Error.Title" = "Nie można zainstalowaÄ helpera";
+
+// Min MacOS Supported
+"Alert.MinSupported.Title" = "NiezgodnoÅÄ z minimalnymi wymaganiami";
+"Alert.MinSupported.Message" = "Xcode %@ wymaga macOS %@, a ty masz macOS %@. Czy nadal chcesz go zainstalowaÄ?";
+
+// Install
+"Alert.Install.Error.Title" = "Nie można zainstalowaÄ Xcode";
+"Alert.InstallArchive.Error.Title" = "Nie można zainstalowaÄ zarchiwizowanego Xcode";
+
+// Update
+"Alert.Update.Error.Title" = "Nie można zaktualizowaÄ wybranej wersji Xcode";
+
+// Active/Select
+"Alert.Select.Error.Title" = "Nie można wybraÄ Xcode";
+
+// Symbolic Links
+"Alert.SymLink.Title" = "Nie można utworzyÄ linku symbolicznego";
+"Alert.SymLink.Message" = "Xcode.app istnieje i nie jest linkiem symbolicznym";
+
+// Post install
+"Alert.PostInstall.Title" = "Nie można wykonaÄ czynnoÅci po-instalacyjnych";
+
+// InstallationErrors
+"InstallationError.DamagedXIP" = "Archiwum \"%@\" jest uszkodzone i nie może zostaÄ rozpakowane.";
+"InstallationError.NotEnoughFreeSpaceToExpandArchive" = "Nie można rozpakowaÄ archiwum \"%@\", ponieważ wolumin nie ma wystarczajÄ
cej iloÅci wolnego miejsca.\n\nZrób wiÄcej miejsca, aby rozpakowaÄ archiwum, a nastÄpnie zainstaluj ponownie Xcode %@, aby kontynuowaÄ instalacjÄ od miejsca, w którym zostaÅa wstrzymana.";
+"InstallationError.FailedToMoveXcodeToApplications" = "Nie udaÅo siÄ przenieÅÄ Xcode do katalogu %@.";
+"InstallationError.FailedSecurityAssessment" = "Xcode %@ nie przeszedÅ testu bezpieczeÅstwa z nastÄpujÄ
cym wynikiem:\n%@\nPozostaje zainstalowany w %@, jeÅli mimo to chcesz go używaÄ.";
+"InstallationError.CodesignVerifyFailed" = "Pobrany Xcode nie przeszedÅ weryfikacji sygnatury kodu z wynikiem:\n%@";
+"InstallationError.UnexpectedCodeSigningIdentity" = "Pobrany Xcode nie ma oczekiwanej sygnatury kodu.\nOtrzymano:\n%@\n%@\nOczekiwano:\n%@\n%@";
+"InstallationError.UnsupportedFileFormat" = "Xcodes nie obsÅuguje (jeszcze) instalowania Xcode z formatu %@.";
+
+"InstallationError.MissingSudoerPassword" = "Brak hasÅa. Spróbuj ponownie.";
+"InstallationError.UnavailableVersion" = "Nie można znaleÅŗÄ wersji %@.";
+"InstallationError.NoNonPrereleaseVersionAvailable" = "Brak wersji nie-przedpremierowych.";
+"InstallationError.NoPrereleaseVersionAvailable" = "Brak wersji przedpremierowych.";
+"InstallationError.MissingUsernameOrPassword" = "Brak nazwy użytkownika lub hasÅa. Spróbuj ponownie.";
+"InstallationError.VersionAlreadyInstalled" = "%@ jest już zainstalowany w %@.";
+"InstallationError.InvalidVersion" = "%@ nie jest prawidÅowym numerem wersji.";
+"InstallationError.VersionNotInstalled" = "%@ nie jest zainstalowany.";
+"InstallationError.PostInstallStepsNotPerformed.Installed" = "Instalacja zostaÅa zakoÅczona, ale niektóre kroki po instalacji nie zostaÅy wykonane automatycznie. ZostanÄ
one wykonane przy pierwszym uruchomieniu Xcode %@.";
+"InstallationError.PostInstallStepsNotPerformed.NotInstalled" = "Instalacja zostaÅa zakoÅczona, ale niektóre kroki po instalacji nie zostaÅy wykonane automatycznie. Xcodes wykonuje te kroki z pomocÄ
helpera z uprawnieniami, który nie jest zainstalowany. Możesz go zainstalowaÄ w Ustawienia > Zaawansowane.\n\nTe kroki zostanÄ
wykonane przy pierwszym uruchomieniu Xcode %@.";
+
+// Installation Steps
+"Downloading" = "Pobieranie";
+"Unarchiving" = "Rozpakowywanie (To może chwilÄ potrwaÄ)";
+"Moving" = "Przenoszenie do %@";
+"TrashingArchive" = "Przenoszenie archiwum do kosza";
+"CheckingSecurity" = "Weryfikacja zabezpieczeÅ";
+"Finishing" = "KoÅczenie";
+
+// Notifications
+"Notification.NewVersionAvailable" = "DostÄpna jest nowa wersja";
+"Notification.FinishedInstalling" = "ZakoÅczono instalacjÄ";
+
+
+"HelperClient.error" = "Nie można komunikowaÄ siÄ z helperem z uprawnieniami.";
+///++
+// Notifications
+"Notification.NewXcodeVersion.Title" = "Nowe wersje Xcode";
+"Notification.NewXcodeVersion.Body" = "DostÄpne sÄ
nowe wersje Xcode do pobrania.";
+
+// WWDC
+"WWDC.Message" = "šØš»āš»š©š¼āš» WesoÅego WWDC %@! šØš½āš»š§š»āš»";
diff --git a/Xcodes/Resources/pt-BR.lproj/Localizable.strings b/Xcodes/Resources/pt-BR.lproj/Localizable.strings
index 68e69cf..9eb73a3 100644
--- a/Xcodes/Resources/pt-BR.lproj/Localizable.strings
+++ b/Xcodes/Resources/pt-BR.lproj/Localizable.strings
@@ -81,7 +81,7 @@
"AutomaticallyCreateSymbolicLink" = "Criar link simbólico para o Xcode.app automaticamente";
"AutomaticallyCreateSymbolicLinkDescription" = "Quando ativar/selecionar uma versão do Xcode, tentar criar um link simbólico chamado Xcode.app no diretório de instalação";
"DataSource" = "Fonte de dados";
-"DataSourceDescription" = "A fonte de dados da Apple copia o site Apple Developer. Sempre mostrarĆ” os lanƧamentos mais recentes que estĆ£o disponĆveis, porĆ©m Ć© mais frĆ”gil.\n\nLanƧamentos do Xcode Ć© uma lista de lanƧamentos do Xcode nĆ£o-oficial. Ć provido como dado formatado, contem informação extra que nĆ£o estĆ” prontamente disponĆvel pela Apple, e Ć© menos provĆ”vel que quebre se a Apple redesenhar o seu site de desenvolvedores.";
+"DataSourceDescription" = "A fonte de dados da Apple copia o site Apple Developer. Sempre mostrarĆ” os lanƧamentos mais recentes que estĆ£o disponĆveis, porĆ©m Ć© mais frĆ”gil.\n\nLanƧamentos do Xcode (Xcode Releases) Ć© uma lista de lanƧamentos do Xcode nĆ£o-oficial. Ć provido como dado formatado, contem informação extra que nĆ£o estĆ” prontamente disponĆvel pela Apple, e Ć© menos provĆ”vel que quebre se a Apple redesenhar o seu site de desenvolvedores.";
"Downloader" = "Baixador";
"DownloaderDescription" = "aria2 usa até 16 conexões para baixar o Xcode 3-5x mais rÔpido que URLSession. EstÔ empacotado como um executÔvel junto com o seu código fonte dentro do Xcodes para conformar com a licensa GPLv2.\n\nURLSession é a API padrão da Apple para performar requisições URL.";
"PrivilegedHelper" = "Ajudante privilegiado";
@@ -89,6 +89,11 @@
"HelperInstalled" = "Ajudante estĆ” instalado";
"HelperNotInstalled" = "Ajudante não estÔ instalado";
"InstallHelper" = "Instalar ajudante";
+"OnSelectDoNothing" = "Manter nome como Xcode-X.X.X.app";
+"OnSelectRenameXcode" = "Sempre renomear para Xcode.app";
+"OnSelectRenameXcodeDescription" = "Ao selecionar, tentar renomear o Xcode ativo para Xcode.app, renomeando o Xcode.app anterior para um nome com a versão.";
+"ShowOpenInRosetta" = "Mostrar opƧao abrir com Rosetta";
+"ShowOpenInRosettaDescription" = "Opção de abrir com o Rosetta serĆ” mostrar onde outras opƧƵes \"Abrir\" estĆ£o disponĆveis. Nota: Isso só serĆ” mostrado pra mĆ”quinas Apple Silicon.";
// Experiment Preference Pane
"Experiments" = "Experiments";
diff --git a/Xcodes/Resources/tr.lproj/Localizable.strings b/Xcodes/Resources/tr.lproj/Localizable.strings
index fd192fd..1cbb514 100644
--- a/Xcodes/Resources/tr.lproj/Localizable.strings
+++ b/Xcodes/Resources/tr.lproj/Localizable.strings
@@ -95,12 +95,16 @@
"AutomaticallyCreateSymbolicLinkDescription" = "Bir Xcode sürümünü Aktif/SeƧ yaparken Xcode.app ismindeki uygulamanın sembolik linkini yükleme klasƶrüne otomatik oluÅturmayı dene";
"OnSelectRenameXcode" = "Her zaman Xcode.app Åeklinde ismi deÄiÅtir";
"OnSelectRenameXcodeDescription" = "SeƧildiÄinde, aktif olan Xcode'u Xcode.app olarak isimlendirmeye ƧalıÅır ve eski Xcode ismine sürüm ismi ekler.";
+
"PrivilegedHelper" = "Ayrıcalıklı Yardımcı";
"PrivilegedHelperDescription" ="Xcodes, root gƶrevlerini yerine getirmek iƧin bir Ayrıcalıklı yardımcı aracı kullanır. Bunlar komut satırındaki sudo gerektiren, yükleme sonrası adımlarını saÄlayan ve Xcode sürümü deÄiÅtiren xcode-select gibi komutlardan ibarettir.\n\nBunu yüklemek iƧin macOS hesap Åifrenizi girmeniz istenecektir.";
"HelperInstalled" = "Yardımcı yüklendi";
"HelperNotInstalled" = "Yardımcı yüklenmedi";
"InstallHelper" = "Yardımcıyı yükle";
+"ShowOpenInRosetta" = "Rosetta ile aƧma seƧeneÄini gƶster";
+"ShowOpenInRosettaDescription" = "Rosetta ile aƧma opsiyonu diÄer uygun \"AƧma\" fonksiyonlarını gƶsterecektir. Not: Bu sadece Apple Silikon makinelerinde gƶzükecektir.";
+
// Experiment Preference Pane
"Experiments" = "Deneyler";
"FasterUnxip" = "Daha Hızlı Unxip";
@@ -159,6 +163,7 @@
"Alert.Uninstall.Title" = "Xcode %@ sürümünü Kaldır?";
"Alert.Uninstall.Message" = "Uygulama Ćƶp Kutusuna taÅınacaktır, fakat silinmeyecektir.";
"Alert.Uninstall.Error.Title" = "Xcode Kaldırılamadı";
+"Alert.Uninstall.Error.Message.FileNotFound" = "\"%@\" dosyası bulunamadı.";
// Cancel Install
"Alert.CancelInstall.Title" = "Xcode %@ sürümünün yüklenmesini durdurmak istediÄinize emin misiniz?";
diff --git a/Xcodes/Resources/unxip b/Xcodes/Resources/unxip
index d8ce15e..46a7f31 100755
Binary files a/Xcodes/Resources/unxip and b/Xcodes/Resources/unxip differ
diff --git a/Xcodes/Resources/zh-Hans.lproj/Localizable.strings b/Xcodes/Resources/zh-Hans.lproj/Localizable.strings
index c18bb9d..3bea058 100644
--- a/Xcodes/Resources/zh-Hans.lproj/Localizable.strings
+++ b/Xcodes/Resources/zh-Hans.lproj/Localizable.strings
@@ -90,7 +90,7 @@
"InstallPathDescription" = "Xcodesä¼åØäøäøŖē®å½äøę£ē“¢åå®č£
ćé»č®¤ļ¼ęØčļ¼äæę/Applicationsćä»»ä½åƹXcodeååØä½ē½®ēåę“é½åÆč½ä¼åƼč“å
¶ä»Appęęå”åę¢å·„ä½ć";
"OnSelectDoNothing" = "äæęåē§°äøŗXcode-X.X.X.app";
-"OnSelectDoNothingDescription" = "éäøę¶ļ¼å°ä¼å°ä¼äæęåēę¬ēåē§°ćä¾å¦Xcode-13.4.1.appć";
+"OnSelectDoNothingDescription" = "éäøę¶ļ¼å°ä¼äæęåēę¬ēåē§°ćä¾å¦Xcode-13.4.1.appć";
"AutomaticallyCreateSymbolicLink" = "čŖåØå建åäøŗXcode.appē软čæę„";
"AutomaticallyCreateSymbolicLinkDescription" = "å½ęæę“»/éå®ęäøŖXcodeēę¬ę¶ļ¼å°čÆåØå®č£
ē®å½å建äøäøŖåäøŗXcode.appē软é¾ę„ć";
"OnSelectRenameXcode" = "ę»ęÆéå½åäøŗXcode.app";
diff --git a/experiment_dark.jpg b/experiment_dark.jpg
deleted file mode 100644
index b71f79b..0000000
Binary files a/experiment_dark.jpg and /dev/null differ
diff --git a/experiment_dark.png b/experiment_dark.png
new file mode 100644
index 0000000..bfb498a
Binary files /dev/null and b/experiment_dark.png differ
diff --git a/experiment_light.jpg b/experiment_light.jpg
deleted file mode 100644
index a547328..0000000
Binary files a/experiment_light.jpg and /dev/null differ
diff --git a/experiment_light.png b/experiment_light.png
new file mode 100644
index 0000000..fc71b91
Binary files /dev/null and b/experiment_light.png differ
diff --git a/nextstep.md b/nextstep.md
new file mode 100644
index 0000000..79aa13d
--- /dev/null
+++ b/nextstep.md
@@ -0,0 +1,15 @@
+## The next step
+
+As Xcodes continues to grow beyond a small little utility used by Apple Developers all over the world to make their lives easier when it comes to downloading, managing and saving their sanity with Xcode, it was time to move the repo away from Robots and Pencils and into it's own managed org.
+
+Starting April 21, 2023, all Xcodes repos are now contained under the `XcodesOrg` organization. https://github.com/XcodesOrg
+
+This change will have no effect on the tools at all, but allows the utilites to grow to the next level. I'm (Matt Kiazyk) still the owner and current sole maintainer, and have no plans to stop.
+
+Xcodes would not be where it is without contributors over the years. It would also not be where it is without each and every one of you sharing the tool.
+
+So from myself - thank you!
+
+Matt Kiazyk - maintainer
+@XcodesApp
+@mattkiazyk
\ No newline at end of file
diff --git a/screenshot_dark.png b/screenshot_dark.png
index 3de73e4..cf4a6d7 100644
Binary files a/screenshot_dark.png and b/screenshot_dark.png differ
diff --git a/screenshot_light.png b/screenshot_light.png
index 62989ca..b4d2dec 100644
Binary files a/screenshot_light.png and b/screenshot_light.png differ