SwiftUI is happening
38
Yggdrasil Backup.xcframework/Info.plist
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>AvailableLibraries</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>macos-arm64_x86_64</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>Yggdrasil.framework</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
<string>x86_64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>macos</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>ios-arm64</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>Yggdrasil.framework</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>ios</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>XFWK</string>
|
||||||
|
<key>XCFrameworkFormatVersion</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -10,6 +10,7 @@ import UIKit
|
||||||
#elseif canImport(AppKit)
|
#elseif canImport(AppKit)
|
||||||
import AppKit
|
import AppKit
|
||||||
#endif
|
#endif
|
||||||
|
import SwiftUI
|
||||||
import Yggdrasil
|
import Yggdrasil
|
||||||
import NetworkExtension
|
import NetworkExtension
|
||||||
|
|
||||||
|
@ -28,12 +29,14 @@ class PlatformItemSource: NSObject {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class ConfigurationProxy: PlatformItemSource {
|
class ConfigurationProxy: PlatformItemSource {
|
||||||
|
private var manager: NETunnelProviderManager?
|
||||||
private var json: Data? = nil
|
private var json: Data? = nil
|
||||||
private var dict: [String: Any]? = nil
|
private var dict: [String: Any]? = nil
|
||||||
|
|
||||||
override init() {
|
init(manager: NETunnelProviderManager? = nil) {
|
||||||
|
self.manager = manager
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.json = MobileGenerateConfigJSON()
|
self.json = MobileGenerateConfigJSON()
|
||||||
do {
|
do {
|
||||||
try self.convertToDict()
|
try self.convertToDict()
|
||||||
|
@ -48,8 +51,10 @@ class ConfigurationProxy: PlatformItemSource {
|
||||||
self.fix()
|
self.fix()
|
||||||
}
|
}
|
||||||
|
|
||||||
init(json: Data) throws {
|
init(json: Data, manager: NETunnelProviderManager? = nil) throws {
|
||||||
|
self.manager = manager
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.json = json
|
self.json = json
|
||||||
try self.convertToDict()
|
try self.convertToDict()
|
||||||
self.fix()
|
self.fix()
|
||||||
|
@ -59,9 +64,10 @@ class ConfigurationProxy: PlatformItemSource {
|
||||||
self.set("Listen", to: [] as [String])
|
self.set("Listen", to: [] as [String])
|
||||||
self.set("AdminListen", to: "none")
|
self.set("AdminListen", to: "none")
|
||||||
self.set("IfName", to: "dummy")
|
self.set("IfName", to: "dummy")
|
||||||
|
// self.set("Peers", to: ["tcp://172.22.97.1.5190", "tls://172.22.97.1:5191"])
|
||||||
|
|
||||||
if self.get("AutoStart") == nil {
|
if self.get("AutoStart") == nil {
|
||||||
self.set("AutoStart", to: ["WiFi": false, "Mobile": false] as [String: Bool])
|
self.set("AutoStart", to: ["Any": false, "WiFi": false, "Mobile": false, "Ethernet": false] as [String: Bool])
|
||||||
}
|
}
|
||||||
|
|
||||||
let multicastInterfaces = self.get("MulticastInterfaces") as? [[String: Any]] ?? []
|
let multicastInterfaces = self.get("MulticastInterfaces") as? [[String: Any]] ?? []
|
||||||
|
@ -88,6 +94,7 @@ class ConfigurationProxy: PlatformItemSource {
|
||||||
var multicastInterfaces = self.get("MulticastInterfaces") as? [[String: Any]] ?? []
|
var multicastInterfaces = self.get("MulticastInterfaces") as? [[String: Any]] ?? []
|
||||||
multicastInterfaces[0]["Beacon"] = newValue
|
multicastInterfaces[0]["Beacon"] = newValue
|
||||||
self.set("MulticastInterfaces", to: multicastInterfaces)
|
self.set("MulticastInterfaces", to: multicastInterfaces)
|
||||||
|
self.trySave()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,10 +110,61 @@ class ConfigurationProxy: PlatformItemSource {
|
||||||
var multicastInterfaces = self.get("MulticastInterfaces") as? [[String: Any]] ?? []
|
var multicastInterfaces = self.get("MulticastInterfaces") as? [[String: Any]] ?? []
|
||||||
multicastInterfaces[0]["Listen"] = newValue
|
multicastInterfaces[0]["Listen"] = newValue
|
||||||
self.set("MulticastInterfaces", to: multicastInterfaces)
|
self.set("MulticastInterfaces", to: multicastInterfaces)
|
||||||
|
self.trySave()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func get(_ key: String) -> Any? {
|
public var autoStartAny: Bool {
|
||||||
|
get {
|
||||||
|
return self.get("Any", inSection: "AutoStart") as? Bool ?? false
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
self.set("Any", inSection: "AutoStart", to: newValue)
|
||||||
|
self.trySave()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var autoStartWiFi: Bool {
|
||||||
|
get {
|
||||||
|
return self.get("WiFi", inSection: "AutoStart") as? Bool ?? false
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
self.set("WiFi", inSection: "AutoStart", to: newValue)
|
||||||
|
self.trySave()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var autoStartEthernet: Bool {
|
||||||
|
get {
|
||||||
|
return self.get("Ethernet", inSection: "AutoStart") as? Bool ?? false
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
self.set("Ethernet", inSection: "AutoStart", to: newValue)
|
||||||
|
self.trySave()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var autoStartMobile: Bool {
|
||||||
|
get {
|
||||||
|
return self.get("Mobile", inSection: "AutoStart") as? Bool ?? false
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
self.set("Mobile", inSection: "AutoStart", to: newValue)
|
||||||
|
self.trySave()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var peers: [String] {
|
||||||
|
get {
|
||||||
|
return self.get("Peers") as? [String] ?? []
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
self.set("Peers", to: newValue)
|
||||||
|
self.trySave()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func get(_ key: String) -> Any? {
|
||||||
if let dict = self.dict {
|
if let dict = self.dict {
|
||||||
if dict.keys.contains(key) {
|
if dict.keys.contains(key) {
|
||||||
return dict[key]
|
return dict[key]
|
||||||
|
@ -115,7 +173,7 @@ class ConfigurationProxy: PlatformItemSource {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func get(_ key: String, inSection section: String) -> Any? {
|
private func get(_ key: String, inSection section: String) -> Any? {
|
||||||
if let dict = self.get(section) as? [String: Any] {
|
if let dict = self.get(section) as? [String: Any] {
|
||||||
if dict.keys.contains(key) {
|
if dict.keys.contains(key) {
|
||||||
return dict[key]
|
return dict[key]
|
||||||
|
@ -124,7 +182,7 @@ class ConfigurationProxy: PlatformItemSource {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func add(_ value: Any, in key: String) {
|
private func add(_ value: Any, in key: String) {
|
||||||
if self.dict != nil {
|
if self.dict != nil {
|
||||||
if self.dict![key] as? [Any] != nil {
|
if self.dict![key] as? [Any] != nil {
|
||||||
var temp = self.dict![key] as? [Any] ?? []
|
var temp = self.dict![key] as? [Any] ?? []
|
||||||
|
@ -134,7 +192,7 @@ class ConfigurationProxy: PlatformItemSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func remove(_ value: String, from key: String) {
|
private func remove(_ value: String, from key: String) {
|
||||||
if self.dict != nil {
|
if self.dict != nil {
|
||||||
if self.dict![key] as? [String] != nil {
|
if self.dict![key] as? [String] != nil {
|
||||||
var temp = self.dict![key] as? [String] ?? []
|
var temp = self.dict![key] as? [String] ?? []
|
||||||
|
@ -146,7 +204,7 @@ class ConfigurationProxy: PlatformItemSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func remove(index: Int, from key: String) {
|
private func remove(index: Int, from key: String) {
|
||||||
if self.dict != nil {
|
if self.dict != nil {
|
||||||
if self.dict![key] as? [Any] != nil {
|
if self.dict![key] as? [Any] != nil {
|
||||||
var temp = self.dict![key] as? [Any] ?? []
|
var temp = self.dict![key] as? [Any] ?? []
|
||||||
|
@ -156,13 +214,13 @@ class ConfigurationProxy: PlatformItemSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func set(_ key: String, to value: Any) {
|
private func set(_ key: String, to value: Any) {
|
||||||
if self.dict != nil {
|
if self.dict != nil {
|
||||||
self.dict![key] = value
|
self.dict![key] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func set(_ key: String, inSection section: String, to value: Any?) {
|
private func set(_ key: String, inSection section: String, to value: Any?) {
|
||||||
if self.dict != nil {
|
if self.dict != nil {
|
||||||
if self.dict!.keys.contains(section), let value = value {
|
if self.dict!.keys.contains(section), let value = value {
|
||||||
var temp = self.dict![section] as? [String: Any] ?? [:]
|
var temp = self.dict![section] as? [String: Any] ?? [:]
|
||||||
|
@ -181,6 +239,12 @@ class ConfigurationProxy: PlatformItemSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func trySave() {
|
||||||
|
if var manager = self.manager {
|
||||||
|
try? self.save(to: &manager)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func save(to manager: inout NETunnelProviderManager) throws {
|
func save(to manager: inout NETunnelProviderManager) throws {
|
||||||
self.fix()
|
self.fix()
|
||||||
if let data = self.data() {
|
if let data = self.data() {
|
||||||
|
@ -192,6 +256,18 @@ class ConfigurationProxy: PlatformItemSource {
|
||||||
|
|
||||||
let disconnectrule = NEOnDemandRuleDisconnect()
|
let disconnectrule = NEOnDemandRuleDisconnect()
|
||||||
var rules: [NEOnDemandRule] = [disconnectrule]
|
var rules: [NEOnDemandRule] = [disconnectrule]
|
||||||
|
if self.get("Any", inSection: "AutoStart") as? Bool ?? false {
|
||||||
|
let wifirule = NEOnDemandRuleConnect()
|
||||||
|
wifirule.interfaceTypeMatch = .any
|
||||||
|
rules.insert(wifirule, at: 0)
|
||||||
|
}
|
||||||
|
#if os(macOS)
|
||||||
|
if self.get("Ethernet", inSection: "AutoStart") as? Bool ?? false {
|
||||||
|
let wifirule = NEOnDemandRuleConnect()
|
||||||
|
wifirule.interfaceTypeMatch = .ethernet
|
||||||
|
rules.insert(wifirule, at: 0)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if self.get("WiFi", inSection: "AutoStart") as? Bool ?? false {
|
if self.get("WiFi", inSection: "AutoStart") as? Bool ?? false {
|
||||||
let wifirule = NEOnDemandRuleConnect()
|
let wifirule = NEOnDemandRuleConnect()
|
||||||
wifirule.interfaceTypeMatch = .wiFi
|
wifirule.interfaceTypeMatch = .wiFi
|
||||||
|
@ -214,8 +290,7 @@ class ConfigurationProxy: PlatformItemSource {
|
||||||
if let error = error {
|
if let error = error {
|
||||||
print(error)
|
print(error)
|
||||||
} else {
|
} else {
|
||||||
print("Save successfully")
|
print("Saved successfully")
|
||||||
NotificationCenter.default.post(name: NSNotification.Name.YggdrasilSettingsUpdated, object: self)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,46 +22,52 @@ typealias ApplicationDelegateAdaptor = NSApplicationDelegateAdaptor
|
||||||
|
|
||||||
class CrossPlatformAppDelegate: PlatformAppDelegate, ObservableObject {
|
class CrossPlatformAppDelegate: PlatformAppDelegate, ObservableObject {
|
||||||
var vpnManager: NETunnelProviderManager = NETunnelProviderManager()
|
var vpnManager: NETunnelProviderManager = NETunnelProviderManager()
|
||||||
|
var yggdrasilConfig: ConfigurationProxy = ConfigurationProxy()
|
||||||
let yggdrasilComponent = "eu.neilalexander.yggdrasil.extension"
|
let yggdrasilComponent = "eu.neilalexander.yggdrasil.extension"
|
||||||
|
private var adminTimer: DispatchSourceTimer?
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(forName: .NEVPNStatusDidChange, object: nil, queue: nil, using: { notification in
|
NotificationCenter.default.addObserver(forName: .NEVPNStatusDidChange, object: nil, queue: nil, using: { notification in
|
||||||
if let conn = notification.object as? NEVPNConnection {
|
if let conn = notification.object as? NEVPNConnection {
|
||||||
self.updateStatus(conn: conn)
|
switch conn.status {
|
||||||
|
case .connected:
|
||||||
|
self.requestSummaryIPC()
|
||||||
|
self.requestStatusIPC()
|
||||||
|
case .disconnecting, .disconnected:
|
||||||
|
self.clearStatus()
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
self.vpnTunnelProviderManagerInit()
|
self.vpnTunnelProviderManagerInit()
|
||||||
self.makeIPCRequests()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggleYggdrasil() {
|
@Published var yggdrasilEnabled: Bool = false {
|
||||||
if !self.yggdrasilEnabled {
|
didSet {
|
||||||
print("Starting VPN tunnel")
|
if yggdrasilEnabled {
|
||||||
|
if vpnManager.connection.status != .connected && vpnManager.connection.status != .connecting {
|
||||||
do {
|
do {
|
||||||
try self.vpnManager.connection.startVPNTunnel()
|
try self.vpnManager.connection.startVPNTunnel()
|
||||||
} catch {
|
} catch {
|
||||||
print("Failed to start VPN tunnel: \(error.localizedDescription)")
|
print("Failed to start VPN tunnel: \(error.localizedDescription)")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
print("Started VPN tunnel")
|
}
|
||||||
} else {
|
} else {
|
||||||
print("Stopping VPN tunnel")
|
if vpnManager.connection.status != .disconnected && vpnManager.connection.status != .disconnecting {
|
||||||
self.vpnManager.connection.stopVPNTunnel()
|
self.vpnManager.connection.stopVPNTunnel()
|
||||||
print("Stopped VPN tunnel")
|
|
||||||
}
|
}
|
||||||
self.yggdrasilEnabled = !self.yggdrasilEnabled
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var yggdrasilConfig: ConfigurationProxy? = nil
|
|
||||||
|
|
||||||
private var adminTimer: DispatchSourceTimer?
|
|
||||||
|
|
||||||
@Published var yggdrasilEnabled: Bool = false
|
|
||||||
@Published var yggdrasilConnected: Bool = false
|
@Published var yggdrasilConnected: Bool = false
|
||||||
|
|
||||||
|
@Published var yggdrasilPublicKey: String = "N/A"
|
||||||
@Published var yggdrasilIP: String = "N/A"
|
@Published var yggdrasilIP: String = "N/A"
|
||||||
@Published var yggdrasilSubnet: String = "N/A"
|
@Published var yggdrasilSubnet: String = "N/A"
|
||||||
@Published var yggdrasilCoords: String = "[]"
|
@Published var yggdrasilCoords: String = "[]"
|
||||||
|
@ -74,39 +80,42 @@ class CrossPlatformAppDelegate: PlatformAppDelegate, ObservableObject {
|
||||||
return Yggdrasil.MobileGetVersion()
|
return Yggdrasil.MobileGetVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
func applicationDidBecomeActive(_ application: PlatformApplication) {
|
func becameActive() {
|
||||||
print("Application became active")
|
print("Application became active")
|
||||||
|
|
||||||
if self.adminTimer == nil {
|
if self.adminTimer == nil {
|
||||||
self.adminTimer = DispatchSource.makeTimerSource(flags: .strict, queue: DispatchQueue(label: "Admin Queue"))
|
self.adminTimer = DispatchSource.makeTimerSource(flags: .strict, queue: .main)
|
||||||
self.adminTimer!.schedule(deadline: DispatchTime.now(), repeating: DispatchTimeInterval.seconds(2), leeway: DispatchTimeInterval.seconds(1))
|
self.adminTimer!.schedule(deadline: DispatchTime.now(), repeating: DispatchTimeInterval.seconds(2), leeway: DispatchTimeInterval.seconds(1))
|
||||||
self.adminTimer!.setEventHandler {
|
self.adminTimer!.setEventHandler {
|
||||||
self.makeIPCRequests()
|
self.updateStatus(conn: self.vpnManager.connection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.adminTimer != nil {
|
if self.adminTimer != nil {
|
||||||
self.adminTimer!.resume()
|
self.adminTimer!.resume()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.requestSummaryIPC()
|
||||||
self.updateStatus(conn: self.vpnManager.connection)
|
self.updateStatus(conn: self.vpnManager.connection)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateStatus(conn: NEVPNConnection) {
|
func becameInactive() {
|
||||||
if conn.status == .connected {
|
print("Application became inactive")
|
||||||
self.makeIPCRequests()
|
|
||||||
} else if conn.status == .disconnecting || conn.status == .disconnected {
|
|
||||||
self.clearStatus()
|
|
||||||
}
|
|
||||||
self.yggdrasilConnected = self.yggdrasilEnabled && self.yggdrasilPeers.count > 0 && self.yggdrasilDHT.count > 0
|
|
||||||
print("Connection status: \(yggdrasilEnabled), \(yggdrasilConnected)")
|
|
||||||
}
|
|
||||||
|
|
||||||
func applicationWillResignActive(_ application: PlatformApplication) {
|
|
||||||
if self.adminTimer != nil {
|
if self.adminTimer != nil {
|
||||||
self.adminTimer!.suspend()
|
self.adminTimer!.suspend()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func becameBackground() {}
|
||||||
|
|
||||||
|
func updateStatus(conn: NEVPNConnection) {
|
||||||
|
if conn.status == .connected {
|
||||||
|
self.requestStatusIPC()
|
||||||
|
} else if conn.status == .disconnecting || conn.status == .disconnected {
|
||||||
|
self.clearStatus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func vpnTunnelProviderManagerInit() {
|
func vpnTunnelProviderManagerInit() {
|
||||||
print("Loading saved managers...")
|
print("Loading saved managers...")
|
||||||
|
|
||||||
|
@ -138,25 +147,24 @@ class CrossPlatformAppDelegate: PlatformAppDelegate, ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.vpnManager.loadFromPreferences(completionHandler: { (error: Error?) in
|
self.vpnManager.loadFromPreferences(completionHandler: { (error: Error?) in
|
||||||
|
var loadedConfig = false
|
||||||
if error == nil {
|
if error == nil {
|
||||||
if let vpnConfig = self.vpnManager.protocolConfiguration as? NETunnelProviderProtocol,
|
if let vpnConfig = self.vpnManager.protocolConfiguration as? NETunnelProviderProtocol,
|
||||||
let confJson = vpnConfig.providerConfiguration!["json"] as? Data {
|
let confJson = vpnConfig.providerConfiguration!["json"] as? Data {
|
||||||
if let loaded = try? ConfigurationProxy(json: confJson) {
|
if let loaded = try? ConfigurationProxy(json: confJson, manager: self.vpnManager) {
|
||||||
print("Found existing protocol configuration")
|
print("Found existing protocol configuration")
|
||||||
self.yggdrasilConfig = loaded
|
self.yggdrasilConfig = loaded
|
||||||
|
loadedConfig = true
|
||||||
} else {
|
} else {
|
||||||
print("Existing protocol configuration is invalid, ignoring")
|
print("Existing protocol configuration is invalid, ignoring")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.yggdrasilConfig == nil {
|
if !loadedConfig {
|
||||||
print("Generating new protocol configuration")
|
print("Generating new protocol configuration")
|
||||||
self.yggdrasilConfig = ConfigurationProxy()
|
self.yggdrasilConfig = ConfigurationProxy(manager: self.vpnManager)
|
||||||
|
try? self.yggdrasilConfig.save(to: &self.vpnManager)
|
||||||
if let config = self.yggdrasilConfig {
|
|
||||||
try? config.save(to: &self.vpnManager)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.vpnManager.localizedDescription = "Yggdrasil"
|
self.vpnManager.localizedDescription = "Yggdrasil"
|
||||||
|
@ -165,56 +173,48 @@ class CrossPlatformAppDelegate: PlatformAppDelegate, ObservableObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeIPCRequests() {
|
func requestSummaryIPC() {
|
||||||
if self.vpnManager.connection.status != .connected {
|
if self.vpnManager.connection.status != .connected {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if let session = self.vpnManager.connection as? NETunnelProviderSession {
|
if let session = self.vpnManager.connection as? NETunnelProviderSession {
|
||||||
try? session.sendProviderMessage("address".data(using: .utf8)!) { (address) in
|
try? session.sendProviderMessage("summary".data(using: .utf8)!) { js in
|
||||||
if let address = address {
|
if let js = js, let summary = try? JSONDecoder().decode(YggdrasilSummary.self, from: js) {
|
||||||
self.yggdrasilIP = String(data: address, encoding: .utf8)!
|
self.yggdrasilEnabled = true
|
||||||
NotificationCenter.default.post(name: .YggdrasilSelfUpdated, object: nil)
|
self.yggdrasilIP = summary.address
|
||||||
|
self.yggdrasilSubnet = summary.subnet
|
||||||
|
self.yggdrasilPublicKey = summary.publicKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try? session.sendProviderMessage("subnet".data(using: .utf8)!) { (subnet) in
|
|
||||||
if let subnet = subnet {
|
|
||||||
self.yggdrasilSubnet = String(data: subnet, encoding: .utf8)!
|
|
||||||
NotificationCenter.default.post(name: .YggdrasilSelfUpdated, object: nil)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try? session.sendProviderMessage("coords".data(using: .utf8)!) { (coords) in
|
|
||||||
if let coords = coords {
|
func requestStatusIPC() {
|
||||||
self.yggdrasilCoords = String(data: coords, encoding: .utf8)!
|
if self.vpnManager.connection.status != .connected {
|
||||||
NotificationCenter.default.post(name: .YggdrasilSelfUpdated, object: nil)
|
return
|
||||||
}
|
}
|
||||||
}
|
if let session = self.vpnManager.connection as? NETunnelProviderSession {
|
||||||
try? session.sendProviderMessage("peers".data(using: .utf8)!) { (peers) in
|
try? session.sendProviderMessage("status".data(using: .utf8)!) { js in
|
||||||
if let peers = peers {
|
if let js = js, let status = try? JSONDecoder().decode(YggdrasilStatus.self, from: js) {
|
||||||
if let jsonResponse = try? JSONSerialization.jsonObject(with: peers, options: []) as? [[String: Any]] {
|
self.yggdrasilCoords = status.coords
|
||||||
|
if let jsonResponse = try? JSONSerialization.jsonObject(with: status.peers, options: []) as? [[String: Any]] {
|
||||||
self.yggdrasilPeers = jsonResponse
|
self.yggdrasilPeers = jsonResponse
|
||||||
NotificationCenter.default.post(name: .YggdrasilPeersUpdated, object: nil)
|
|
||||||
}
|
}
|
||||||
}
|
if let jsonResponse = try? JSONSerialization.jsonObject(with: status.dht, options: []) as? [[String: Any]] {
|
||||||
}
|
|
||||||
try? session.sendProviderMessage("dht".data(using: .utf8)!) { (peers) in
|
|
||||||
if let peers = peers {
|
|
||||||
if let jsonResponse = try? JSONSerialization.jsonObject(with: peers, options: []) as? [[String: Any]] {
|
|
||||||
self.yggdrasilDHT = jsonResponse
|
self.yggdrasilDHT = jsonResponse
|
||||||
NotificationCenter.default.post(name: .YggdrasilDHTUpdated, object: nil)
|
|
||||||
}
|
}
|
||||||
|
self.yggdrasilConnected = self.yggdrasilEnabled && self.yggdrasilPeers.count > 0 && self.yggdrasilDHT.count > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearStatus() {
|
func clearStatus() {
|
||||||
|
self.yggdrasilConnected = false
|
||||||
self.yggdrasilIP = "N/A"
|
self.yggdrasilIP = "N/A"
|
||||||
self.yggdrasilSubnet = "N/A"
|
self.yggdrasilSubnet = "N/A"
|
||||||
self.yggdrasilCoords = "[]"
|
self.yggdrasilCoords = "[]"
|
||||||
self.yggdrasilPeers = []
|
self.yggdrasilPeers = []
|
||||||
self.yggdrasilDHT = []
|
self.yggdrasilDHT = []
|
||||||
NotificationCenter.default.post(name: .YggdrasilSelfUpdated, object: nil)
|
|
||||||
NotificationCenter.default.post(name: .YggdrasilPeersUpdated, object: nil)
|
|
||||||
NotificationCenter.default.post(name: .YggdrasilDHTUpdated, object: nil)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
21
Yggdrasil Network Cross-Platform/IPCResponses.swift
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
//
|
||||||
|
// IPCResponses.swift
|
||||||
|
// YggdrasilNetwork
|
||||||
|
//
|
||||||
|
// Created by Neil Alexander on 20/02/2019.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct YggdrasilSummary: Codable {
|
||||||
|
var address: String
|
||||||
|
var subnet: String
|
||||||
|
var publicKey: String
|
||||||
|
}
|
||||||
|
|
||||||
|
struct YggdrasilStatus: Codable {
|
||||||
|
var enabled: Bool
|
||||||
|
var coords: String
|
||||||
|
var peers: Data
|
||||||
|
var dht: Data
|
||||||
|
}
|
|
@ -1,19 +0,0 @@
|
||||||
//
|
|
||||||
// NSNotification.swift
|
|
||||||
// YggdrasilNetwork
|
|
||||||
//
|
|
||||||
// Created by Neil Alexander on 20/02/2019.
|
|
||||||
//
|
|
||||||
|
|
||||||
#if canImport(UIKit)
|
|
||||||
import UIKit
|
|
||||||
#elseif canImport(AppKit)
|
|
||||||
import AppKit
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extension Notification.Name {
|
|
||||||
static let YggdrasilSelfUpdated = Notification.Name("YggdrasilSelfUpdated")
|
|
||||||
static let YggdrasilPeersUpdated = Notification.Name("YggdrasilPeersUpdated")
|
|
||||||
static let YggdrasilSettingsUpdated = Notification.Name("YggdrasilSettingsUpdated")
|
|
||||||
static let YggdrasilDHTUpdated = Notification.Name("YggdrasilDHTUpdated")
|
|
||||||
}
|
|
|
@ -55,6 +55,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||||
if let fd = self.tunnelFileDescriptor {
|
if let fd = self.tunnelFileDescriptor {
|
||||||
do {
|
do {
|
||||||
try self.yggdrasil.takeOverTUN(fd)
|
try self.yggdrasil.takeOverTUN(fd)
|
||||||
|
NSLog("Yggdrasil taken over TUN successfully")
|
||||||
} catch {
|
} catch {
|
||||||
NSLog("Taking over TUN produced an error: " + error.localizedDescription)
|
NSLog("Taking over TUN produced an error: " + error.localizedDescription)
|
||||||
err = error
|
err = error
|
||||||
|
@ -82,6 +83,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||||
NSLog("Yggdrasil completion handler called")
|
NSLog("Yggdrasil completion handler called")
|
||||||
completionHandler(nil)
|
completionHandler(nil)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
NSLog("Error in Yggdrasil startTunnel: No configuration JSON found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,16 +97,27 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||||
override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil) {
|
override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil) {
|
||||||
let request = String(data: messageData, encoding: .utf8)
|
let request = String(data: messageData, encoding: .utf8)
|
||||||
switch request {
|
switch request {
|
||||||
case "address":
|
case "summary":
|
||||||
completionHandler?(self.yggdrasil.getAddressString().data(using: .utf8))
|
let summary = YggdrasilSummary(
|
||||||
case "subnet":
|
address: self.yggdrasil.getAddressString(),
|
||||||
completionHandler?(self.yggdrasil.getSubnetString().data(using: .utf8))
|
subnet: self.yggdrasil.getSubnetString(),
|
||||||
case "coords":
|
publicKey: self.yggdrasil.getPublicKeyString()
|
||||||
completionHandler?(self.yggdrasil.getCoordsString().data(using: .utf8))
|
)
|
||||||
case "peers":
|
if let json = try? JSONEncoder().encode(summary) {
|
||||||
completionHandler?(self.yggdrasil.getPeersJSON().data(using: .utf8))
|
completionHandler?(json)
|
||||||
case "dht":
|
}
|
||||||
completionHandler?(self.yggdrasil.getDHTJSON().data(using: .utf8))
|
|
||||||
|
case "status":
|
||||||
|
let status = YggdrasilStatus(
|
||||||
|
enabled: true,
|
||||||
|
coords: self.yggdrasil.getCoordsString(),
|
||||||
|
peers: self.yggdrasil.getPeersJSON().data(using: .utf8) ?? Data(),
|
||||||
|
dht: self.yggdrasil.getDHTJSON().data(using: .utf8) ?? Data()
|
||||||
|
)
|
||||||
|
if let json = try? JSONEncoder().encode(status) {
|
||||||
|
completionHandler?(json)
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
completionHandler?(nil)
|
completionHandler?(nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,5 +20,7 @@
|
||||||
</array>
|
</array>
|
||||||
<key>com.apple.security.network.client</key>
|
<key>com.apple.security.network.client</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>com.apple.security.network.server</key>
|
||||||
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
|
@ -1,16 +0,0 @@
|
||||||
//
|
|
||||||
// AppDelegate+AppDelegateExtension.h
|
|
||||||
// Yggdrasil Network
|
|
||||||
//
|
|
||||||
// Created by Neil Alexander on 11/01/2019.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
|
||||||
|
|
||||||
@interface AppDelegate ()
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
|
|
@ -1,15 +0,0 @@
|
||||||
import UIKit
|
|
||||||
|
|
||||||
@UIApplicationMain
|
|
||||||
class AppDelegate: CrossPlatformAppDelegate {
|
|
||||||
var window: UIWindow?
|
|
||||||
|
|
||||||
let configDir = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true)[0]
|
|
||||||
|
|
||||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
|
||||||
// Override point for customization after application launch
|
|
||||||
self.vpnTunnelProviderManagerInit()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"size" : "20x20",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"size" : "20x20",
|
|
||||||
"scale" : "3x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"size" : "29x29",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"size" : "29x29",
|
|
||||||
"scale" : "3x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"size" : "40x40",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"size" : "40x40",
|
|
||||||
"scale" : "3x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "60x60",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "drawing copy-1.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "60x60",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "drawing copy.png",
|
|
||||||
"scale" : "3x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"size" : "20x20",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"size" : "20x20",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"size" : "29x29",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"size" : "29x29",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"size" : "40x40",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"size" : "40x40",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "76x76",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "drawing copy-2.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "76x76",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "drawing copy-3.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "83.5x83.5",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "drawing copy-5.png",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "1024x1024",
|
|
||||||
"idiom" : "ios-marketing",
|
|
||||||
"filename" : "drawing copy-4.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4 KiB |
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"filename" : "img1.png",
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"appearances" : [
|
|
||||||
{
|
|
||||||
"appearance" : "luminosity",
|
|
||||||
"value" : "dark"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"filename" : "img1w.png",
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename" : "img2.png",
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"appearances" : [
|
|
||||||
{
|
|
||||||
"appearance" : "luminosity",
|
|
||||||
"value" : "dark"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"filename" : "img2w.png",
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename" : "img3.png",
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "3x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"appearances" : [
|
|
||||||
{
|
|
||||||
"appearance" : "luminosity",
|
|
||||||
"value" : "dark"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"filename" : "img3w.png",
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "3x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 61 KiB |
|
@ -1,20 +0,0 @@
|
||||||
//
|
|
||||||
// Data.swift
|
|
||||||
// YggdrasilNetworkExtension
|
|
||||||
//
|
|
||||||
// Created by Neil on 15/11/2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
extension Data {
|
|
||||||
/// This computed value is only needed because of [this](https://github.com/golang/go/issues/33745) issue in the
|
|
||||||
/// golang/go repository. It is a workaround until the problem is solved upstream.
|
|
||||||
///
|
|
||||||
/// The data object is converted into an array of bytes and than returned wrapped in an `NSMutableData` object. In
|
|
||||||
/// thas way Gomobile takes it as it is without copying. The Swift side remains responsible for garbage collection.
|
|
||||||
var mutable: Data {
|
|
||||||
var array = [UInt8](self)
|
|
||||||
return NSMutableData(bytes: &array, length: self.count) as Data
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
import Foundation
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
extension UIDevice {
|
|
||||||
/// A Boolean value indicating whether the device has cellular data capabilities (true) or not (false).
|
|
||||||
var hasCellularCapabilites: Bool {
|
|
||||||
var addrs: UnsafeMutablePointer<ifaddrs>?
|
|
||||||
var cursor: UnsafeMutablePointer<ifaddrs>?
|
|
||||||
|
|
||||||
defer { freeifaddrs(addrs) }
|
|
||||||
|
|
||||||
guard getifaddrs(&addrs) == 0 else { return false }
|
|
||||||
cursor = addrs
|
|
||||||
|
|
||||||
while cursor != nil {
|
|
||||||
guard
|
|
||||||
let utf8String = cursor?.pointee.ifa_name,
|
|
||||||
let name = NSString(utf8String: utf8String),
|
|
||||||
name == "pdp_ip0"
|
|
||||||
else {
|
|
||||||
cursor = cursor?.pointee.ifa_next
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
|
||||||
<key>CFBundleDisplayName</key>
|
|
||||||
<string>Yggdrasil</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>$(PRODUCT_NAME)</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>APPL</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>0.1</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
|
||||||
<key>LSApplicationCategoryType</key>
|
|
||||||
<string>public.app-category.utilities</string>
|
|
||||||
<key>LSRequiresIPhoneOS</key>
|
|
||||||
<true/>
|
|
||||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
|
||||||
<true/>
|
|
||||||
<key>UIFileSharingEnabled</key>
|
|
||||||
<true/>
|
|
||||||
<key>UILaunchStoryboardName</key>
|
|
||||||
<string>LaunchScreen</string>
|
|
||||||
<key>UIMainStoryboardFile</key>
|
|
||||||
<string>Main</string>
|
|
||||||
<key>UIRequiredDeviceCapabilities</key>
|
|
||||||
<array>
|
|
||||||
<string>armv7</string>
|
|
||||||
</array>
|
|
||||||
<key>UISupportedInterfaceOrientations</key>
|
|
||||||
<array>
|
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
|
||||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
|
||||||
</array>
|
|
||||||
<key>UTExportedTypeDeclarations</key>
|
|
||||||
<array>
|
|
||||||
<dict>
|
|
||||||
<key>UTTypeConformsTo</key>
|
|
||||||
<array>
|
|
||||||
<string>public.text</string>
|
|
||||||
</array>
|
|
||||||
<key>UTTypeDescription</key>
|
|
||||||
<string>Yggdrasil Configuration File</string>
|
|
||||||
<key>UTTypeIconFiles</key>
|
|
||||||
<array/>
|
|
||||||
<key>UTTypeIdentifier</key>
|
|
||||||
<string>eu.neilalexander.yggdrasil.configuration</string>
|
|
||||||
<key>UTTypeTagSpecification</key>
|
|
||||||
<dict>
|
|
||||||
<key>public.filename-extension</key>
|
|
||||||
<array>
|
|
||||||
<string>yggconf</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
|
@ -1,60 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
|
||||||
<device id="retina4_7" orientation="portrait" appearance="dark"/>
|
|
||||||
<dependencies>
|
|
||||||
<deployment identifier="iOS"/>
|
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
|
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
|
||||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
|
||||||
</dependencies>
|
|
||||||
<scenes>
|
|
||||||
<!--View Controller-->
|
|
||||||
<scene sceneID="EHf-IW-A2E">
|
|
||||||
<objects>
|
|
||||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
|
||||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="YggdrasilNetwork" translatesAutoresizingMaskIntoConstraints="NO" id="3Lc-gG-kep">
|
|
||||||
<rect key="frame" x="28" y="219.5" width="319" height="128"/>
|
|
||||||
<color key="tintColor" systemColor="labelColor"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="width" secondItem="3Lc-gG-kep" secondAttribute="height" multiplier="159:64" id="NYe-AY-mCL"/>
|
|
||||||
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="400" id="lIj-gT-vW9"/>
|
|
||||||
</constraints>
|
|
||||||
</imageView>
|
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Experimental" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0Nr-Vm-h9W">
|
|
||||||
<rect key="frame" x="138" y="626" width="99" height="21"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="3Lc-gG-kep" secondAttribute="trailing" constant="28" id="J9j-Ek-mVq"/>
|
|
||||||
<constraint firstItem="3Lc-gG-kep" firstAttribute="centerY" secondItem="6Tk-OE-BBY" secondAttribute="centerY" constant="-50" id="MLF-C3-5Is"/>
|
|
||||||
<constraint firstItem="3Lc-gG-kep" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="28" id="VpK-lC-s00"/>
|
|
||||||
<constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="0Nr-Vm-h9W" secondAttribute="bottom" constant="20" id="WcT-Cw-bXi"/>
|
|
||||||
<constraint firstItem="0Nr-Vm-h9W" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="ZHc-EA-sHG"/>
|
|
||||||
<constraint firstItem="3Lc-gG-kep" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="xej-Yh-XPz"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
|
||||||
</viewController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="52" y="374.66266866566718"/>
|
|
||||||
</scene>
|
|
||||||
</scenes>
|
|
||||||
<resources>
|
|
||||||
<image name="YggdrasilNetwork" width="480" height="157"/>
|
|
||||||
<systemColor name="labelColor">
|
|
||||||
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
</systemColor>
|
|
||||||
<systemColor name="systemBackgroundColor">
|
|
||||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
</systemColor>
|
|
||||||
</resources>
|
|
||||||
</document>
|
|
|
@ -1,674 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="sjP-mj-LKX">
|
|
||||||
<device id="ipad10_9rounded" orientation="portrait" layout="fullscreen" appearance="light"/>
|
|
||||||
<dependencies>
|
|
||||||
<deployment identifier="iOS"/>
|
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
|
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
|
||||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
|
||||||
</dependencies>
|
|
||||||
<scenes>
|
|
||||||
<!--Peers-->
|
|
||||||
<scene sceneID="YjI-Ak-tYt">
|
|
||||||
<objects>
|
|
||||||
<tableViewController title="Peers" id="Aro-kj-1Us" customClass="PeersViewController" customModule="YggdrasilNetwork" customModuleProvider="target" sceneMemberID="viewController">
|
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="jrG-5P-x67">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="704" height="995.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<prototypes>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="configuredPeerPrototype" textLabel="s5X-wa-HWH" style="IBUITableViewCellStyleDefault" id="8Oo-lj-bGn">
|
|
||||||
<rect key="frame" x="20" y="49.5" width="664" height="43.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="8Oo-lj-bGn" id="l78-DB-hkK">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="664" height="43.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="(discovered)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="s5X-wa-HWH">
|
|
||||||
<rect key="frame" x="16" y="0.0" width="632" height="43.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="discoveredPeerPrototype" textLabel="DBc-bQ-Fql" detailTextLabel="6Zr-Ab-5mg" style="IBUITableViewCellStyleSubtitle" id="GeY-vZ-Kfa">
|
|
||||||
<rect key="frame" x="20" y="93" width="664" height="55.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="GeY-vZ-Kfa" id="CVl-gJ-x3R">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="664" height="55.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="(static)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="DBc-bQ-Fql" customClass="CopyableLabel" customModule="YggdrasilNetwork" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="16" y="10" width="54" height="20.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="200:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="6Zr-Ab-5mg">
|
|
||||||
<rect key="frame" x="16" y="31.5" width="26" height="14.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="menuPrototype" textLabel="hGp-hS-MXO" style="IBUITableViewCellStyleDefault" id="X8B-Ij-Uxu">
|
|
||||||
<rect key="frame" x="20" y="148.5" width="664" height="43.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="X8B-Ij-Uxu" id="VFl-pZ-ioq">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="638.5" height="43.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Menu item" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="hGp-hS-MXO">
|
|
||||||
<rect key="frame" x="16" y="0.0" width="614.5" height="43.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="togglePrototype" id="7yi-ur-bht" customClass="ToggleTableViewCell" customModule="YggdrasilNetwork" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="20" y="192" width="664" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="7yi-ur-bht" id="xEb-l3-99b">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="664" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Toggle item" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ij2-ls-8ZT">
|
|
||||||
<rect key="frame" x="16" y="12.5" width="575" height="21"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="MYo-S3-kzH">
|
|
||||||
<rect key="frame" x="599" y="7" width="51" height="31.5"/>
|
|
||||||
</switch>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="MYo-S3-kzH" secondAttribute="bottom" constant="5.5" id="GE4-ve-zue"/>
|
|
||||||
<constraint firstItem="MYo-S3-kzH" firstAttribute="leading" secondItem="ij2-ls-8ZT" secondAttribute="trailing" constant="8" id="HY3-fl-iyt"/>
|
|
||||||
<constraint firstItem="ij2-ls-8ZT" firstAttribute="leading" secondItem="xEb-l3-99b" secondAttribute="leadingMargin" id="K5Q-In-8A5"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="MYo-S3-kzH" secondAttribute="trailing" constant="16" id="OfU-Jc-Jh0"/>
|
|
||||||
<constraint firstItem="ij2-ls-8ZT" firstAttribute="centerY" secondItem="MYo-S3-kzH" secondAttribute="centerY" id="g5U-4E-XRi"/>
|
|
||||||
<constraint firstItem="MYo-S3-kzH" firstAttribute="top" secondItem="xEb-l3-99b" secondAttribute="top" constant="7" id="wvd-yp-ouw"/>
|
|
||||||
</constraints>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
<connections>
|
|
||||||
<outlet property="label" destination="ij2-ls-8ZT" id="4kY-1u-gbw"/>
|
|
||||||
<outlet property="toggle" destination="MYo-S3-kzH" id="WDg-LO-UM4"/>
|
|
||||||
</connections>
|
|
||||||
</tableViewCell>
|
|
||||||
</prototypes>
|
|
||||||
<sections/>
|
|
||||||
<connections>
|
|
||||||
<outlet property="dataSource" destination="Aro-kj-1Us" id="LKO-i9-QW7"/>
|
|
||||||
<outlet property="delegate" destination="Aro-kj-1Us" id="Gth-NL-fBx"/>
|
|
||||||
</connections>
|
|
||||||
</tableView>
|
|
||||||
<toolbarItems>
|
|
||||||
<barButtonItem systemItem="add" id="MOW-Lh-hSQ">
|
|
||||||
<connections>
|
|
||||||
<action selector="addNewPeerButtonPressed:" destination="Aro-kj-1Us" id="CS3-Z6-tRA"/>
|
|
||||||
</connections>
|
|
||||||
</barButtonItem>
|
|
||||||
</toolbarItems>
|
|
||||||
<navigationItem key="navigationItem" title="Peers" id="4pr-Fq-FKY"/>
|
|
||||||
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
|
|
||||||
<connections>
|
|
||||||
<outlet property="addButtonItem" destination="MOW-Lh-hSQ" id="2UM-tD-SnA"/>
|
|
||||||
<outlet property="peerTable" destination="jrG-5P-x67" id="RPw-J3-r1C"/>
|
|
||||||
</connections>
|
|
||||||
</tableViewController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="nJT-Ej-FI5" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="1761" y="1212"/>
|
|
||||||
</scene>
|
|
||||||
<!--Peers-->
|
|
||||||
<scene sceneID="psN-bH-gYF">
|
|
||||||
<objects>
|
|
||||||
<navigationController title="Peers" id="LPj-bu-hdp" sceneMemberID="viewController">
|
|
||||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="ifJ-0T-bJ4">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="499.5" height="50"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
</navigationBar>
|
|
||||||
<connections>
|
|
||||||
<segue destination="Aro-kj-1Us" kind="relationship" relationship="rootViewController" id="rED-QI-0E9"/>
|
|
||||||
</connections>
|
|
||||||
</navigationController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="gCh-Is-VRG" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="1761" y="426"/>
|
|
||||||
</scene>
|
|
||||||
<!--Settings-->
|
|
||||||
<scene sceneID="VfF-sj-c5P">
|
|
||||||
<objects>
|
|
||||||
<tableViewController title="Settings" id="FeQ-BB-bF5" customClass="SettingsViewController" customModule="YggdrasilNetwork" customModuleProvider="target" sceneMemberID="viewController">
|
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="Cd3-Fg-6d3">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="499.5" height="1180"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<sections>
|
|
||||||
<tableViewSection headerTitle="Node Info" footerTitle="Information entered here is public and may be shown on network maps." id="su8-4b-N3L">
|
|
||||||
<cells>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="nxn-IW-t8I">
|
|
||||||
<rect key="frame" x="20" y="49.5" width="459.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="nxn-IW-t8I" id="a0m-Mn-9fE">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="459.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<textField opaque="NO" contentMode="scaleToFill" horizontalCompressionResistancePriority="250" contentHorizontalAlignment="trailing" contentVerticalAlignment="center" placeholder="None" textAlignment="right" adjustsFontForContentSizeCategory="YES" minimumFontSize="9" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="iRg-tv-diq">
|
|
||||||
<rect key="frame" x="134" y="1" width="310.5" height="43"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="height" constant="43" id="cRe-aZ-mWa"/>
|
|
||||||
</constraints>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
|
||||||
<textInputTraits key="textInputTraits" autocapitalizationType="words" keyboardType="alphabet" enablesReturnKeyAutomatically="YES" textContentType="nickname"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="deviceNameEdited:" destination="FeQ-BB-bF5" eventType="editingDidEnd" id="lfQ-f7-dSt"/>
|
|
||||||
</connections>
|
|
||||||
</textField>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Device Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="102" translatesAutoresizingMaskIntoConstraints="NO" id="ieL-P9-WNc">
|
|
||||||
<rect key="frame" x="16" y="0.0" width="102" height="44"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="height" constant="44" id="2cx-q4-by8"/>
|
|
||||||
<constraint firstAttribute="width" constant="102" id="MVL-qb-gJw"/>
|
|
||||||
</constraints>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="iRg-tv-diq" secondAttribute="trailing" constant="15" id="5Ww-uH-INm"/>
|
|
||||||
<constraint firstItem="ieL-P9-WNc" firstAttribute="top" secondItem="a0m-Mn-9fE" secondAttribute="top" id="Hoe-Le-Zln"/>
|
|
||||||
<constraint firstItem="iRg-tv-diq" firstAttribute="leading" secondItem="ieL-P9-WNc" secondAttribute="trailing" constant="16" id="JXX-kn-TTD"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="ieL-P9-WNc" secondAttribute="bottom" id="MOQ-cH-sUE"/>
|
|
||||||
<constraint firstItem="iRg-tv-diq" firstAttribute="top" secondItem="a0m-Mn-9fE" secondAttribute="top" constant="1" id="O3n-WK-oyd"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="iRg-tv-diq" secondAttribute="bottom" id="heq-bT-FXa"/>
|
|
||||||
<constraint firstItem="ieL-P9-WNc" firstAttribute="leading" secondItem="a0m-Mn-9fE" secondAttribute="leading" constant="16" id="hy7-uL-DHk"/>
|
|
||||||
</constraints>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
</cells>
|
|
||||||
</tableViewSection>
|
|
||||||
<tableViewSection headerTitle="Automatically Start On" footerTitle="Yggdrasil will be started automatically when connected to the above networks." id="bjf-vx-Swh">
|
|
||||||
<cells>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="checkmark" indentationWidth="10" textLabel="NYE-Pu-5Gk" style="IBUITableViewCellStyleDefault" id="pwi-5Y-UxD">
|
|
||||||
<rect key="frame" x="20" y="159.5" width="459.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="pwi-5Y-UxD" id="631-3X-gfX">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="423" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Wi-Fi" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="NYE-Pu-5Gk">
|
|
||||||
<rect key="frame" x="16" y="0.0" width="399" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<color key="tintColor" red="0.20340806249999999" green="0.47218620779999998" blue="0.96475774049999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="checkmark" indentationWidth="10" textLabel="ZdY-uX-KE6" style="IBUITableViewCellStyleDefault" id="iwW-oY-kqV">
|
|
||||||
<rect key="frame" x="20" y="203.5" width="459.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="iwW-oY-kqV" id="Pe0-bO-Sd1">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="423" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Mobile Network" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ZdY-uX-KE6">
|
|
||||||
<rect key="frame" x="16" y="0.0" width="399" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<color key="tintColor" red="0.20340806249999999" green="0.47218620779999998" blue="0.96475774049999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
</cells>
|
|
||||||
</tableViewSection>
|
|
||||||
<tableViewSection headerTitle="Public Key" footerTitle="Your public key forms your identity on the network. It is safe to be shared." id="Bqi-0N-6vQ">
|
|
||||||
<cells>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" textLabel="SeD-oT-h3h" style="IBUITableViewCellStyleDefault" id="80f-wf-ING">
|
|
||||||
<rect key="frame" x="20" y="327.5" width="459.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="80f-wf-ING" id="fed-pT-rbF">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="459.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Signing" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="SeD-oT-h3h" customClass="CopyableLabel" customModule="YggdrasilNetwork" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="16" y="0.0" width="427.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" name="Menlo-Regular" family="Menlo" pointSize="16"/>
|
|
||||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
</cells>
|
|
||||||
</tableViewSection>
|
|
||||||
<tableViewSection headerTitle="Backup" id="mD0-CO-qvR">
|
|
||||||
<string key="footerTitle">Configuration will be exported to the Files app. Your configuration contains your private key which is extremely sensitive. You must not share it with others.</string>
|
|
||||||
<cells>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="0zV-IH-vF4" style="IBUITableViewCellStyleDefault" id="IgR-eA-aHt">
|
|
||||||
<rect key="frame" x="20" y="437.5" width="459.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="IgR-eA-aHt" id="wsZ-KR-yUu">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="459.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Import configuration" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="0zV-IH-vF4">
|
|
||||||
<rect key="frame" x="16" y="0.0" width="427.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<color key="tintColor" red="0.20340806249999999" green="0.47218620779999998" blue="0.96475774049999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<color key="textColor" red="0.20340806249999999" green="0.47218620779999998" blue="0.96475774049999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="n0W-r2-Cp7" style="IBUITableViewCellStyleDefault" id="Fgj-Ug-A8R">
|
|
||||||
<rect key="frame" x="20" y="481.5" width="459.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Fgj-Ug-A8R" id="l0v-9n-Tzb">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="459.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Export configuration" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="n0W-r2-Cp7">
|
|
||||||
<rect key="frame" x="16" y="0.0" width="427.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<color key="tintColor" red="0.20340806249999999" green="0.47218620779999998" blue="0.96475774049999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<color key="textColor" red="0.20340806249999999" green="0.47218620779999998" blue="0.96475774049999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
</cells>
|
|
||||||
</tableViewSection>
|
|
||||||
<tableViewSection headerTitle="Reset" footerTitle="Resetting will overwrite with newly generated configuration. Your public keys and IP address on the network will change." id="QPd-T4-5id">
|
|
||||||
<cells>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="Jc5-vz-oTA" style="IBUITableViewCellStyleDefault" id="Cgi-Yk-esa">
|
|
||||||
<rect key="frame" x="20" y="619.5" width="459.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Cgi-Yk-esa" id="qMT-ha-vJK">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="459.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Reset configuration" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Jc5-vz-oTA">
|
|
||||||
<rect key="frame" x="16" y="0.0" width="427.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<color key="tintColor" red="0.20340806249999999" green="0.47218620779999998" blue="0.96475774049999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<color key="textColor" red="0.81077963080000004" green="0.26273393630000003" blue="0.2154698987" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
</cells>
|
|
||||||
</tableViewSection>
|
|
||||||
</sections>
|
|
||||||
<connections>
|
|
||||||
<outlet property="dataSource" destination="FeQ-BB-bF5" id="UKi-St-qym"/>
|
|
||||||
<outlet property="delegate" destination="FeQ-BB-bF5" id="Pbu-nP-u0N"/>
|
|
||||||
</connections>
|
|
||||||
</tableView>
|
|
||||||
<navigationItem key="navigationItem" title="Settings" id="13i-0q-HI5"/>
|
|
||||||
<connections>
|
|
||||||
<outlet property="autoStartMobileCell" destination="iwW-oY-kqV" id="kDV-jT-IBR"/>
|
|
||||||
<outlet property="autoStartWiFiCell" destination="pwi-5Y-UxD" id="UJo-BZ-aXf"/>
|
|
||||||
<outlet property="deviceNameField" destination="iRg-tv-diq" id="ffH-UY-BAT"/>
|
|
||||||
<outlet property="signingPublicKeyLabel" destination="SeD-oT-h3h" id="5eK-yA-3LM"/>
|
|
||||||
</connections>
|
|
||||||
</tableViewController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="eco-Zl-sgd" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="2571" y="1212"/>
|
|
||||||
</scene>
|
|
||||||
<!--Settings-->
|
|
||||||
<scene sceneID="ot0-wd-NE5">
|
|
||||||
<objects>
|
|
||||||
<navigationController title="Settings" id="g4p-RE-Qtl" sceneMemberID="viewController">
|
|
||||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="p6Z-I0-Zza">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="499.5" height="50"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
</navigationBar>
|
|
||||||
<connections>
|
|
||||||
<segue destination="FeQ-BB-bF5" kind="relationship" relationship="rootViewController" id="pga-rT-3Jc"/>
|
|
||||||
</connections>
|
|
||||||
</navigationController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="tUJ-Lk-YoU" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="2571" y="426"/>
|
|
||||||
</scene>
|
|
||||||
<!--Yggdrasil-->
|
|
||||||
<scene sceneID="zY7-dE-7Ay">
|
|
||||||
<objects>
|
|
||||||
<tableViewController title="Yggdrasil" id="s1Q-pC-XBn" customClass="TableViewController" customModule="YggdrasilNetwork" customModuleProvider="target" sceneMemberID="viewController">
|
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="vHG-eF-QEu">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="420" height="1180"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<sections>
|
|
||||||
<tableViewSection headerTitle="Status" id="Jwl-JP-RuU">
|
|
||||||
<cells>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="49H-YI-ie3">
|
|
||||||
<rect key="frame" x="116" y="49.5" width="288" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="49H-YI-ie3" id="ZPC-T2-kah">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="288" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Enable Yggdrasil" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="alk-ml-y9V">
|
|
||||||
<rect key="frame" x="16" y="12" width="126" height="20"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="trailing" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="qre-Dz-rWw">
|
|
||||||
<rect key="frame" x="223" y="7" width="51" height="31"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="toggleVPNStatus:forEvent:" destination="s1Q-pC-XBn" eventType="valueChanged" id="Mvh-gf-qg0"/>
|
|
||||||
</connections>
|
|
||||||
</switch>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="qre-Dz-rWw" firstAttribute="top" secondItem="ZPC-T2-kah" secondAttribute="top" constant="7" id="6Yd-ne-dsL"/>
|
|
||||||
<constraint firstItem="alk-ml-y9V" firstAttribute="top" secondItem="ZPC-T2-kah" secondAttribute="top" constant="12" id="Du8-1c-XP8"/>
|
|
||||||
<constraint firstAttribute="trailing" secondItem="qre-Dz-rWw" secondAttribute="trailing" constant="16" id="SUT-kR-Vtj"/>
|
|
||||||
<constraint firstAttribute="bottom" secondItem="alk-ml-y9V" secondAttribute="bottom" constant="12" id="Sz7-IF-DrB"/>
|
|
||||||
<constraint firstItem="alk-ml-y9V" firstAttribute="leading" secondItem="ZPC-T2-kah" secondAttribute="leading" constant="16" id="kGE-t0-Aph"/>
|
|
||||||
</constraints>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" textLabel="dZv-7O-fZv" style="IBUITableViewCellStyleDefault" id="m9f-Bi-XeH">
|
|
||||||
<rect key="frame" x="116" y="93.5" width="288" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="m9f-Bi-XeH" id="utU-J9-9M8">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="288" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="No active connections" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="dZv-7O-fZv">
|
|
||||||
<rect key="frame" x="16" y="0.0" width="256" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/>
|
|
||||||
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
</cells>
|
|
||||||
</tableViewSection>
|
|
||||||
<tableViewSection headerTitle="Statistics" id="nJf-RJ-qUC">
|
|
||||||
<cells>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="0.0" textLabel="MUj-Ni-chU" detailTextLabel="ceY-dc-u9v" style="IBUITableViewCellStyleValue1" id="Ela-vk-pnR">
|
|
||||||
<rect key="frame" x="116" y="187.5" width="288" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Ela-vk-pnR" id="fnr-ZG-yiF">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="288" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="IP" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="MUj-Ni-chU">
|
|
||||||
<rect key="frame" x="16" y="12" width="14.5" height="20.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="N/A" textAlignment="right" lineBreakMode="headTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" adjustsFontForContentSizeCategory="YES" id="ceY-dc-u9v" customClass="CopyableLabel" customModule="YggdrasilNetwork" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="248.5" y="15" width="23.5" height="17"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
|
||||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="blue" indentationWidth="10" textLabel="Q8j-k7-HTk" detailTextLabel="MLH-EY-4VQ" style="IBUITableViewCellStyleValue1" id="1BH-o1-n90">
|
|
||||||
<rect key="frame" x="116" y="231.5" width="288" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="1BH-o1-n90" id="aLD-3W-BlB">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="288" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Subnet" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Q8j-k7-HTk">
|
|
||||||
<rect key="frame" x="16" y="12" width="54.5" height="20.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="N/A" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="MLH-EY-4VQ" customClass="CopyableLabel" customModule="YggdrasilNetwork" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="248.5" y="15" width="23.5" height="17"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
|
||||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" textLabel="9jY-kM-E6n" detailTextLabel="JYJ-ov-02q" style="IBUITableViewCellStyleValue1" id="g00-iP-grJ">
|
|
||||||
<rect key="frame" x="116" y="275.5" width="288" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="g00-iP-grJ" id="C21-9O-H5d">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="288" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Coordinates" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="9jY-kM-E6n">
|
|
||||||
<rect key="frame" x="16" y="12" width="92.5" height="20.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="[]" textAlignment="right" lineBreakMode="headTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" adjustsFontForContentSizeCategory="YES" id="JYJ-ov-02q" customClass="CopyableLabel" customModule="YggdrasilNetwork" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="261.5" y="15" width="10.5" height="17"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
|
||||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
</cells>
|
|
||||||
</tableViewSection>
|
|
||||||
<tableViewSection headerTitle="Configuration" footerTitle="You must re-enable Yggdrasil after modifying Peers or Settings to make any changes effective." id="gRf-Ts-qeJ">
|
|
||||||
<cells>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="blue" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="rT6-UD-Cn5" detailTextLabel="vc0-Rq-wtq" style="IBUITableViewCellStyleValue1" id="qRF-c3-JyG">
|
|
||||||
<rect key="frame" x="116" y="377" width="288" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="qRF-c3-JyG" id="gcO-mr-jgp">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="262.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Peers" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="rT6-UD-Cn5">
|
|
||||||
<rect key="frame" x="16" y="12" width="43.5" height="20.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="No peers" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="vc0-Rq-wtq">
|
|
||||||
<rect key="frame" x="196" y="15" width="58.5" height="17"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
|
||||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
<connections>
|
|
||||||
<segue destination="LPj-bu-hdp" kind="showDetail" id="tx6-4f-Vm0"/>
|
|
||||||
</connections>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="blue" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="CPw-Tm-fZl" style="IBUITableViewCellStyleDefault" id="Ugm-vO-zYq">
|
|
||||||
<rect key="frame" x="116" y="421" width="288" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Ugm-vO-zYq" id="Jkh-no-wta">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="262.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Settings" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="CPw-Tm-fZl">
|
|
||||||
<rect key="frame" x="16" y="0.0" width="238.5" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
<connections>
|
|
||||||
<segue destination="g4p-RE-Qtl" kind="showDetail" id="hEo-ra-aPX"/>
|
|
||||||
</connections>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="it5-My-OoQ" detailTextLabel="1mF-wN-xLU" style="IBUITableViewCellStyleValue1" id="SNP-Qf-NZg">
|
|
||||||
<rect key="frame" x="116" y="465" width="288" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="SNP-Qf-NZg" id="2mC-0D-KCT">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="288" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Version" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="it5-My-OoQ">
|
|
||||||
<rect key="frame" x="16" y="12" width="57" height="20.5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Unknown" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="1mF-wN-xLU">
|
|
||||||
<rect key="frame" x="211.5" y="15" width="60.5" height="17"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
|
||||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
</cells>
|
|
||||||
</tableViewSection>
|
|
||||||
</sections>
|
|
||||||
<connections>
|
|
||||||
<outlet property="dataSource" destination="s1Q-pC-XBn" id="ASk-mj-jQP"/>
|
|
||||||
<outlet property="delegate" destination="s1Q-pC-XBn" id="3yd-vi-tqY"/>
|
|
||||||
</connections>
|
|
||||||
</tableView>
|
|
||||||
<navigationItem key="navigationItem" title="Yggdrasil" leftItemsSupplementBackButton="YES" largeTitleDisplayMode="always" id="zEJ-Ur-D8L">
|
|
||||||
<barButtonItem key="backBarButtonItem" title="Status" id="kru-5r-NnH"/>
|
|
||||||
<barButtonItem key="rightBarButtonItem" systemItem="refresh" id="SK1-2o-4fg">
|
|
||||||
<connections>
|
|
||||||
<action selector="onRefreshButton:" destination="s1Q-pC-XBn" id="Tqe-lm-dDv"/>
|
|
||||||
</connections>
|
|
||||||
</barButtonItem>
|
|
||||||
</navigationItem>
|
|
||||||
<connections>
|
|
||||||
<outlet property="connectedStatusLabel" destination="dZv-7O-fZv" id="DfM-cR-8VQ"/>
|
|
||||||
<outlet property="statsSelfCoords" destination="JYJ-ov-02q" id="lcM-hA-tsY"/>
|
|
||||||
<outlet property="statsSelfCoordsCell" destination="g00-iP-grJ" id="Ho9-VC-QSe"/>
|
|
||||||
<outlet property="statsSelfIP" destination="ceY-dc-u9v" id="Zob-e3-cVr"/>
|
|
||||||
<outlet property="statsSelfIPCell" destination="Ela-vk-pnR" id="01S-pD-zJc"/>
|
|
||||||
<outlet property="statsSelfPeers" destination="vc0-Rq-wtq" id="usQ-EN-040"/>
|
|
||||||
<outlet property="statsSelfSubnet" destination="MLH-EY-4VQ" id="33U-qS-FUE"/>
|
|
||||||
<outlet property="statsSelfSubnetCell" destination="1BH-o1-n90" id="Njb-oQ-W5C"/>
|
|
||||||
<outlet property="statsVersion" destination="1mF-wN-xLU" id="drW-io-cYk"/>
|
|
||||||
<outlet property="toggleConnect" destination="qre-Dz-rWw" id="Oox-v4-K0x"/>
|
|
||||||
<outlet property="toggleLabel" destination="alk-ml-y9V" id="o4p-Xn-ofm"/>
|
|
||||||
<outlet property="toggleTableView" destination="vHG-eF-QEu" id="iNr-0v-RoB"/>
|
|
||||||
</connections>
|
|
||||||
</tableViewController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Nbt-Cc-GRV" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="2571" y="-338"/>
|
|
||||||
</scene>
|
|
||||||
<!--View Controller-->
|
|
||||||
<scene sceneID="VMS-X3-A7G">
|
|
||||||
<objects>
|
|
||||||
<viewController id="j4D-sS-gKL" sceneMemberID="viewController">
|
|
||||||
<view key="view" contentMode="scaleToFill" id="eFY-KL-QD6">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="499.5" height="1180"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.10000000000000001" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="YggdrasilNetwork" translatesAutoresizingMaskIntoConstraints="NO" id="pD8-7E-1Fb">
|
|
||||||
<rect key="frame" x="100" y="511" width="299.5" height="98"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="width" secondItem="pD8-7E-1Fb" secondAttribute="height" multiplier="480:157" id="60u-Jo-0oL"/>
|
|
||||||
</constraints>
|
|
||||||
</imageView>
|
|
||||||
</subviews>
|
|
||||||
<viewLayoutGuide key="safeArea" id="99T-rn-Aup"/>
|
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="pD8-7E-1Fb" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="99T-rn-Aup" secondAttribute="leading" constant="100" id="ByQ-oN-wNr"/>
|
|
||||||
<constraint firstItem="99T-rn-Aup" firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="pD8-7E-1Fb" secondAttribute="trailing" constant="100" id="b14-Ic-a2R"/>
|
|
||||||
<constraint firstItem="pD8-7E-1Fb" firstAttribute="centerX" secondItem="eFY-KL-QD6" secondAttribute="centerX" id="kZ4-ij-5GT"/>
|
|
||||||
<constraint firstItem="pD8-7E-1Fb" firstAttribute="centerY" secondItem="eFY-KL-QD6" secondAttribute="centerY" constant="-30" id="xxi-aE-iPO"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
|
||||||
</viewController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Z9V-gc-NxA" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="1474" y="-1008"/>
|
|
||||||
</scene>
|
|
||||||
<!--Yggdrasil-->
|
|
||||||
<scene sceneID="NHm-je-2CC">
|
|
||||||
<objects>
|
|
||||||
<navigationController title="Yggdrasil" id="Dz7-et-ljx" sceneMemberID="viewController">
|
|
||||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="uxo-U2-UUS">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="420" height="102"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
</navigationBar>
|
|
||||||
<toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="6hK-6f-rI2">
|
|
||||||
<rect key="frame" x="100" y="0.0" width="0.0" height="0.0"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
</toolbar>
|
|
||||||
<connections>
|
|
||||||
<segue destination="s1Q-pC-XBn" kind="relationship" relationship="rootViewController" id="foA-iq-EPh"/>
|
|
||||||
</connections>
|
|
||||||
</navigationController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="nYt-zg-2Gb" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="1762" y="-337"/>
|
|
||||||
</scene>
|
|
||||||
<!--Split View Controller-->
|
|
||||||
<scene sceneID="9co-Q0-BvB">
|
|
||||||
<objects>
|
|
||||||
<splitViewController modalPresentationStyle="pageSheet" allowDoubleColumnStyle="YES" preferredDisplayMode="beside" behavior="tile" presentsWithGesture="NO" id="sjP-mj-LKX" customClass="SplitViewController" customModule="YggdrasilNetwork" customModuleProvider="target" sceneMemberID="viewController">
|
|
||||||
<connections>
|
|
||||||
<segue destination="Dz7-et-ljx" kind="relationship" relationship="masterViewController" id="QfQ-La-EfI"/>
|
|
||||||
<segue destination="j4D-sS-gKL" kind="relationship" relationship="detailViewController" id="RcM-Sy-h8j"/>
|
|
||||||
</connections>
|
|
||||||
</splitViewController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Fe3-ey-WRA" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="811" y="-5"/>
|
|
||||||
</scene>
|
|
||||||
</scenes>
|
|
||||||
<resources>
|
|
||||||
<image name="YggdrasilNetwork" width="480" height="157"/>
|
|
||||||
<systemColor name="secondaryLabelColor">
|
|
||||||
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
</systemColor>
|
|
||||||
<systemColor name="systemBackgroundColor">
|
|
||||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
</systemColor>
|
|
||||||
</resources>
|
|
||||||
</document>
|
|
|
@ -1,52 +0,0 @@
|
||||||
//
|
|
||||||
// CopyableLabel.swift
|
|
||||||
// YggdrasilNetwork
|
|
||||||
//
|
|
||||||
// Created by Neil Alexander on 26/02/2019.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
class CopyableLabel: UILabel {
|
|
||||||
override public var canBecomeFirstResponder: Bool {
|
|
||||||
get {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
|
||||||
super.init(frame: frame)
|
|
||||||
self.isUserInteractionEnabled = true
|
|
||||||
self.addGestureRecognizer(UILongPressGestureRecognizer(
|
|
||||||
target: self,
|
|
||||||
action: #selector(showMenu(sender:))
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
|
||||||
super.init(coder: aDecoder)
|
|
||||||
self.isUserInteractionEnabled = true
|
|
||||||
self.addGestureRecognizer(UILongPressGestureRecognizer(
|
|
||||||
target: self,
|
|
||||||
action: #selector(showMenu(sender:))
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
override func copy(_ sender: Any?) {
|
|
||||||
UIPasteboard.general.string = text
|
|
||||||
UIMenuController.shared.setMenuVisible(false, animated: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func showMenu(sender: Any?) {
|
|
||||||
self.becomeFirstResponder()
|
|
||||||
let menu = UIMenuController.shared
|
|
||||||
if !menu.isMenuVisible {
|
|
||||||
menu.setTargetRect(bounds, in: self)
|
|
||||||
menu.setMenuVisible(true, animated: true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
|
|
||||||
return (action == #selector(copy(_:)))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
//
|
|
||||||
// ToggleTableViewCell.swift
|
|
||||||
// YggdrasilNetwork
|
|
||||||
//
|
|
||||||
// Created by Neil Alexander on 07/01/2019.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
class ToggleTableViewCell: UITableViewCell {
|
|
||||||
|
|
||||||
@IBOutlet weak var label: UILabel!
|
|
||||||
@IBOutlet weak var toggle: UISwitch!
|
|
||||||
|
|
||||||
override func awakeFromNib() {
|
|
||||||
super.awakeFromNib()
|
|
||||||
// Initialization code
|
|
||||||
}
|
|
||||||
|
|
||||||
override func setSelected(_ selected: Bool, animated: Bool) {
|
|
||||||
super.setSelected(selected, animated: animated)
|
|
||||||
|
|
||||||
// Configure the view for the selected state
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,286 +0,0 @@
|
||||||
//
|
|
||||||
// PeersViewController.swift
|
|
||||||
// YggdrasilNetwork
|
|
||||||
//
|
|
||||||
// Created by Neil Alexander on 07/01/2019.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import NetworkExtension
|
|
||||||
import CoreTelephony
|
|
||||||
|
|
||||||
class PeersViewController: UITableViewController {
|
|
||||||
var app = UIApplication.shared.delegate as! AppDelegate
|
|
||||||
var config: [String: Any]? = nil
|
|
||||||
|
|
||||||
@IBOutlet var peerTable: UITableView!
|
|
||||||
@IBOutlet weak var addButtonItem: UIBarButtonItem!
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
|
||||||
super.viewDidLoad()
|
|
||||||
|
|
||||||
if let proto = self.app.vpnManager.protocolConfiguration as? NETunnelProviderProtocol {
|
|
||||||
config = proto.providerConfiguration ?? nil
|
|
||||||
}
|
|
||||||
|
|
||||||
self.navigationItem.rightBarButtonItems = [
|
|
||||||
self.editButtonItem,
|
|
||||||
self.addButtonItem
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilPeersUpdated), name: NSNotification.Name.YggdrasilPeersUpdated, object: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewWillDisappear(_ animated: Bool) {
|
|
||||||
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.YggdrasilPeersUpdated, object: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func onYggdrasilPeersUpdated(notification: NSNotification) {
|
|
||||||
peerTable.reloadData()
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Table view data source
|
|
||||||
|
|
||||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
|
||||||
return 3
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
||||||
switch section {
|
|
||||||
case 0: return app.yggdrasilPeers.count
|
|
||||||
case 1:
|
|
||||||
if let config = self.app.yggdrasilConfig {
|
|
||||||
if let peers = config.get("Peers") as? [String] {
|
|
||||||
return peers.count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
case 2:
|
|
||||||
return 2
|
|
||||||
default: return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
|
||||||
switch indexPath.section {
|
|
||||||
case 0:
|
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: "discoveredPeerPrototype", for: indexPath)
|
|
||||||
let peers = app.yggdrasilPeers.sorted { (a, b) -> Bool in
|
|
||||||
return (a["Port"] as! Int) < (b["Port"] as! Int)
|
|
||||||
}
|
|
||||||
|
|
||||||
if indexPath.row < peers.count {
|
|
||||||
let value = peers[indexPath.row]
|
|
||||||
let proto = value["Protocol"] as? String ?? "tcp"
|
|
||||||
let remote = value["Remote"] as? String ?? "unknown"
|
|
||||||
let prio = value["Priority"] as? Int ?? 0
|
|
||||||
|
|
||||||
cell.textLabel?.text = "\(value["IP"] ?? "(unknown)")"
|
|
||||||
cell.detailTextLabel?.text = "\(proto.uppercased()): \(remote)"
|
|
||||||
}
|
|
||||||
return cell
|
|
||||||
case 1:
|
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: "configuredPeerPrototype", for: indexPath)
|
|
||||||
if let config = self.app.yggdrasilConfig {
|
|
||||||
if let peers = config.get("Peers") as? [String] {
|
|
||||||
cell.textLabel?.text = peers[indexPath.last!]
|
|
||||||
} else {
|
|
||||||
cell.textLabel?.text = "(unknown)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cell
|
|
||||||
case 2:
|
|
||||||
switch indexPath.last {
|
|
||||||
case 0:
|
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: "togglePrototype", for: indexPath) as! ToggleTableViewCell
|
|
||||||
cell.isUserInteractionEnabled = true
|
|
||||||
cell.label?.text = "Discoverable over multicast"
|
|
||||||
cell.label?.isEnabled = true
|
|
||||||
cell.toggle?.addTarget(self, action: #selector(toggledMulticastBeacons), for: .valueChanged)
|
|
||||||
cell.toggle?.isEnabled = true
|
|
||||||
if let config = self.app.yggdrasilConfig {
|
|
||||||
cell.toggle?.isOn = config.multicastBeacons
|
|
||||||
}
|
|
||||||
return cell
|
|
||||||
case 1:
|
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: "togglePrototype", for: indexPath) as! ToggleTableViewCell
|
|
||||||
cell.isUserInteractionEnabled = true
|
|
||||||
cell.label?.text = "Search for multicast peers"
|
|
||||||
cell.label?.isEnabled = true
|
|
||||||
cell.toggle?.addTarget(self, action: #selector(toggledMulticastListen), for: .valueChanged)
|
|
||||||
cell.toggle?.isEnabled = true
|
|
||||||
if let config = self.app.yggdrasilConfig {
|
|
||||||
cell.toggle?.isOn = config.multicastListen
|
|
||||||
}
|
|
||||||
return cell
|
|
||||||
default:
|
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: "menuPrototype", for: indexPath)
|
|
||||||
cell.isUserInteractionEnabled = false
|
|
||||||
cell.textLabel?.text = "Unknown"
|
|
||||||
cell.textLabel?.isEnabled = true
|
|
||||||
return cell
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: "configuredPeerPrototype", for: indexPath)
|
|
||||||
cell.textLabel?.text = "(unknown)"
|
|
||||||
return cell
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func format(bytes: Double) -> String {
|
|
||||||
guard bytes > 0 else {
|
|
||||||
return "0 bytes"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adapted from http://stackoverflow.com/a/18650828
|
|
||||||
let suffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
|
|
||||||
let k: Double = 1000
|
|
||||||
let i = floor(log(bytes) / log(k))
|
|
||||||
|
|
||||||
// Format number with thousands separator and everything below 1 GB with no decimal places.
|
|
||||||
let numberFormatter = NumberFormatter()
|
|
||||||
numberFormatter.maximumFractionDigits = i < 3 ? 0 : 1
|
|
||||||
numberFormatter.numberStyle = .decimal
|
|
||||||
|
|
||||||
let numberString = numberFormatter.string(from: NSNumber(value: bytes / pow(k, i))) ?? "Unknown"
|
|
||||||
let suffix = suffixes[Int(i)]
|
|
||||||
return "\(numberString) \(suffix)"
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func toggledMulticastBeacons(_ sender: UISwitch) {
|
|
||||||
if let config = self.app.yggdrasilConfig {
|
|
||||||
config.multicastBeacons = sender.isOn
|
|
||||||
try? config.save(to: &app.vpnManager)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func toggledMulticastListen(_ sender: UISwitch) {
|
|
||||||
if let config = self.app.yggdrasilConfig {
|
|
||||||
config.multicastListen = sender.isOn
|
|
||||||
try? config.save(to: &app.vpnManager)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
|
||||||
switch section {
|
|
||||||
case 0:
|
|
||||||
if self.app.yggdrasilPeers.count > 0 {
|
|
||||||
return "Connected Peers"
|
|
||||||
}
|
|
||||||
return "No peers currently connected"
|
|
||||||
case 1:
|
|
||||||
if let config = self.app.yggdrasilConfig {
|
|
||||||
if let peers = config.get("Peers") as? [String] {
|
|
||||||
if peers.count > 0 {
|
|
||||||
return "Configured Peers"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "No peers currently configured"
|
|
||||||
case 2:
|
|
||||||
return "Peer Connectivity"
|
|
||||||
default: return "(Unknown)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
|
|
||||||
switch section {
|
|
||||||
case 1:
|
|
||||||
return "Yggdrasil will automatically attempt to connect to configured peers when started. If you configure more than one peer, your device may carry traffic on behalf of other network nodes. Avoid this by configuring only a single peer."
|
|
||||||
case 2:
|
|
||||||
var str = "Multicast peers will be discovered on the same Wi-Fi network or via USB."
|
|
||||||
if UIDevice.current.hasCellularCapabilites {
|
|
||||||
str += " Data charges may apply when using mobile data. You can prevent mobile data usage in the device settings."
|
|
||||||
}
|
|
||||||
return str
|
|
||||||
default: return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
|
|
||||||
return indexPath.first == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
|
|
||||||
switch indexPath.first {
|
|
||||||
case 0:
|
|
||||||
return [UITableViewRowAction(style: UITableViewRowAction.Style.default, title: "Disconnect", handler: { (action, index) in
|
|
||||||
|
|
||||||
})]
|
|
||||||
case 1:
|
|
||||||
return [UITableViewRowAction(style: UITableViewRowAction.Style.normal, title: "Remove", handler: { (action, index) in
|
|
||||||
print(action, index)
|
|
||||||
if let config = self.app.yggdrasilConfig {
|
|
||||||
config.remove(index: index.last!, from: "Peers")
|
|
||||||
do {
|
|
||||||
try config.save(to: &self.app.vpnManager)
|
|
||||||
tableView.reloadSections(IndexSet(integer: 1), with: UITableView.RowAnimation.automatic)
|
|
||||||
} catch {
|
|
||||||
let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
|
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
|
||||||
self.parent?.present(alert, animated: true, completion: nil)
|
|
||||||
print("Error removing: \(error)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})]
|
|
||||||
default:
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
||||||
switch indexPath.first {
|
|
||||||
case 2:
|
|
||||||
if let last = indexPath.last, last == 2 {
|
|
||||||
UIApplication.shared.open(NSURL(string:UIApplication.openSettingsURLString)! as URL, options: [:]) { (result) in
|
|
||||||
NSLog("Result " + result.description)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
tableView.deselectRow(at: indexPath, animated: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction func addNewPeerButtonPressed(_ sender: UIBarButtonItem) {
|
|
||||||
let alert = UIAlertController(title: "Add Configured Peer", message: """
|
|
||||||
Enter the full URI of the peer to add. Yggdrasil will automatically connect to this peer when started.
|
|
||||||
""", preferredStyle: UIAlertController.Style.alert)
|
|
||||||
let action = UIAlertAction(title: "Add", style: .default) { (alertAction) in
|
|
||||||
let textField = alert.textFields![0] as UITextField
|
|
||||||
if let text = textField.text?.trimmingCharacters(in: .whitespacesAndNewlines) {
|
|
||||||
if let config = self.app.yggdrasilConfig {
|
|
||||||
if let peers = config.get("Peers") as? [String], !peers.contains(text) {
|
|
||||||
config.add(text, in: "Peers")
|
|
||||||
do {
|
|
||||||
try config.save(to: &self.app.vpnManager)
|
|
||||||
if let index = config.get("Peers") as? [String] {
|
|
||||||
self.peerTable.insertRows(at: [IndexPath(indexes: [1, index.count-1])], with: .automatic)
|
|
||||||
self.peerTable.reloadSections(IndexSet(integer: 1), with: UITableView.RowAnimation.automatic)
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
|
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
|
||||||
self.parent?.present(alert, animated: true, completion: nil)
|
|
||||||
print("Add error: \(error)")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let alert = UIAlertController(title: "Error", message: "Peer already exists", preferredStyle: .alert)
|
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
|
||||||
self.parent?.present(alert, animated: true, completion: nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let cancel = UIAlertAction(title: "Cancel", style: .cancel)
|
|
||||||
alert.addTextField { (textField) in
|
|
||||||
textField.placeholder = "tcp://hostname:port"
|
|
||||||
}
|
|
||||||
alert.addAction(action)
|
|
||||||
alert.addAction(cancel)
|
|
||||||
self.present(alert, animated: true, completion: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,135 +0,0 @@
|
||||||
//
|
|
||||||
// SettingsTableViewController.swift
|
|
||||||
// YggdrasilNetwork
|
|
||||||
//
|
|
||||||
// Created by Neil Alexander on 03/01/2019.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import NetworkExtension
|
|
||||||
|
|
||||||
class SettingsViewController: UITableViewController, UIDocumentBrowserViewControllerDelegate {
|
|
||||||
var app = UIApplication.shared.delegate as! AppDelegate
|
|
||||||
|
|
||||||
@IBOutlet weak var deviceNameField: UITextField!
|
|
||||||
|
|
||||||
@IBOutlet weak var signingPublicKeyLabel: UILabel!
|
|
||||||
|
|
||||||
@IBOutlet weak var autoStartWiFiCell: UITableViewCell!
|
|
||||||
@IBOutlet weak var autoStartMobileCell: UITableViewCell!
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
|
||||||
super.viewDidLoad()
|
|
||||||
|
|
||||||
if let config = self.app.yggdrasilConfig {
|
|
||||||
deviceNameField.text = config.get("name", inSection: "NodeInfo") as? String ?? ""
|
|
||||||
signingPublicKeyLabel.text = config.get("PublicKey") as? String ?? config.get("SigningPublicKey") as? String ?? "Unknown"
|
|
||||||
|
|
||||||
autoStartWiFiCell.accessoryType = config.get("WiFi", inSection: "AutoStart") as? Bool ?? false ? .checkmark : .none
|
|
||||||
autoStartMobileCell.accessoryType = config.get("Mobile", inSection: "AutoStart") as? Bool ?? false ? .checkmark : .none
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction func deviceNameEdited(_ sender: UITextField) {
|
|
||||||
if let config = self.app.yggdrasilConfig {
|
|
||||||
config.set("name", inSection: "NodeInfo", to: sender.text)
|
|
||||||
try? config.save(to: &app.vpnManager)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
||||||
switch indexPath.first {
|
|
||||||
case 1:
|
|
||||||
let settings = [
|
|
||||||
"WiFi",
|
|
||||||
"Mobile"
|
|
||||||
]
|
|
||||||
if let cell = tableView.cellForRow(at: indexPath) {
|
|
||||||
cell.accessoryType = cell.accessoryType == .checkmark ? .none : .checkmark
|
|
||||||
if let config = self.app.yggdrasilConfig {
|
|
||||||
config.set(settings[indexPath.last!], inSection: "AutoStart", to: cell.accessoryType == .checkmark)
|
|
||||||
try? config.save(to: &app.vpnManager)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
switch indexPath.last {
|
|
||||||
case 0: // import
|
|
||||||
if #available(iOS 11.0, *) {
|
|
||||||
let open = UIDocumentBrowserViewController(forOpeningFilesWithContentTypes: ["eu.neilalexander.yggdrasil.configuration"])
|
|
||||||
open.delegate = self
|
|
||||||
open.allowsDocumentCreation = false
|
|
||||||
open.allowsPickingMultipleItems = false
|
|
||||||
open.additionalTrailingNavigationBarButtonItems = [ UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelDocumentBrowser)) ]
|
|
||||||
self.present(open, animated: true, completion: nil)
|
|
||||||
} else {
|
|
||||||
let alert = UIAlertController(title: "Import Configuration", message: "Not supported on this version of iOS!", preferredStyle: .alert)
|
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
|
||||||
self.present(alert, animated: true, completion: nil)
|
|
||||||
}
|
|
||||||
case 1: // export
|
|
||||||
if let config = self.app.yggdrasilConfig, let data = config.data() {
|
|
||||||
var fileURL: URL?
|
|
||||||
var fileDir: URL?
|
|
||||||
do {
|
|
||||||
let dateFormatter = DateFormatter()
|
|
||||||
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
|
|
||||||
dateFormatter.dateFormat = "yyyy-MM-dd"
|
|
||||||
let date = dateFormatter.string(from: Date())
|
|
||||||
fileDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
|
|
||||||
fileURL = fileDir?.appendingPathComponent("Yggdrasil Backup \(date).yggconf")
|
|
||||||
try? data.write(to: fileURL!)
|
|
||||||
} catch {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if let dir = fileDir {
|
|
||||||
let sharedurl = dir.absoluteString.replacingOccurrences(of: "file://", with: "shareddocuments://")
|
|
||||||
let furl: URL = URL(string: sharedurl)!
|
|
||||||
UIApplication.shared.open(furl, options: [:], completionHandler: nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 4:
|
|
||||||
let alert = UIAlertController(title: "Warning", message: "This operation will reset your configuration and generate new keys. This is not reversible unless your configuration has been exported. Changes will not take effect until the next time Yggdrasil is restarted.", preferredStyle: .alert)
|
|
||||||
alert.addAction(UIAlertAction(title: "Reset", style: .destructive, handler: { action in
|
|
||||||
self.app.yggdrasilConfig = ConfigurationProxy()
|
|
||||||
if let config = self.app.yggdrasilConfig {
|
|
||||||
try? config.save(to: &self.app.vpnManager)
|
|
||||||
self.viewDidLoad()
|
|
||||||
}}))
|
|
||||||
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
|
|
||||||
self.present(alert, animated: true, completion: nil)
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
tableView.deselectRow(at: indexPath, animated: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func cancelDocumentBrowser() {
|
|
||||||
self.dismiss(animated: true, completion: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func documentBrowser(_ controller: UIDocumentBrowserViewController, didPickDocumentsAt documentURLs: [URL]) {
|
|
||||||
do {
|
|
||||||
if let url = documentURLs.first {
|
|
||||||
let data = try Data(contentsOf: url)
|
|
||||||
let conf = try ConfigurationProxy(json: data)
|
|
||||||
try conf.save(to: &self.app.vpnManager)
|
|
||||||
self.app.yggdrasilConfig = conf
|
|
||||||
|
|
||||||
controller.dismiss(animated: true, completion: nil)
|
|
||||||
let alert = UIAlertController(title: "Import Configuration", message: "Configuration file has been imported.", preferredStyle: .alert)
|
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
|
||||||
self.present(alert, animated: true, completion: nil)
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
controller.dismiss(animated: true, completion: nil)
|
|
||||||
let alert = UIAlertController(title: "Import Failed", message: "Unable to import this configuration file.", preferredStyle: .alert)
|
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
|
||||||
self.present(alert, animated: true, completion: nil)
|
|
||||||
}
|
|
||||||
self.viewDidLoad()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
//
|
|
||||||
// SplitViewController.swift
|
|
||||||
// YggdrasilNetwork
|
|
||||||
//
|
|
||||||
// Created by Neil Alexander on 02/01/2019.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
class SplitViewController: UISplitViewController, UISplitViewControllerDelegate {
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
|
||||||
super.viewDidLoad()
|
|
||||||
self.delegate = self
|
|
||||||
self.preferredDisplayMode = .allVisible
|
|
||||||
}
|
|
||||||
|
|
||||||
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(iOS 14.0,*)
|
|
||||||
func splitViewController(_ svc: UISplitViewController, topColumnForCollapsingToProposedTopColumn proposedTopColumn: UISplitViewController.Column) -> UISplitViewController.Column {
|
|
||||||
return .primary
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,137 +0,0 @@
|
||||||
import UIKit
|
|
||||||
import NetworkExtension
|
|
||||||
import Yggdrasil
|
|
||||||
|
|
||||||
class TableViewController: UITableViewController {
|
|
||||||
var app = UIApplication.shared.delegate as! AppDelegate
|
|
||||||
|
|
||||||
@IBOutlet var connectedStatusLabel: UILabel!
|
|
||||||
|
|
||||||
@IBOutlet var toggleTableView: UITableView!
|
|
||||||
@IBOutlet var toggleLabel: UILabel!
|
|
||||||
@IBOutlet var toggleConnect: UISwitch!
|
|
||||||
|
|
||||||
@IBOutlet weak var statsSelfIPCell: UITableViewCell!
|
|
||||||
@IBOutlet weak var statsSelfSubnetCell: UITableViewCell!
|
|
||||||
@IBOutlet weak var statsSelfCoordsCell: UITableViewCell!
|
|
||||||
|
|
||||||
@IBOutlet var statsSelfIP: UILabel!
|
|
||||||
@IBOutlet var statsSelfSubnet: UILabel!
|
|
||||||
@IBOutlet var statsSelfCoords: UILabel!
|
|
||||||
@IBOutlet var statsSelfPeers: UILabel!
|
|
||||||
|
|
||||||
@IBOutlet var statsVersion: UILabel!
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilSelfUpdated), name: NSNotification.Name.YggdrasilSelfUpdated, object: nil)
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilPeersUpdated), name: NSNotification.Name.YggdrasilPeersUpdated, object: nil)
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilDHTUpdated), name: NSNotification.Name.YggdrasilDHTUpdated, object: nil)
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilSettingsUpdated), name: NSNotification.Name.YggdrasilSettingsUpdated, object: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction func onRefreshButton(_ sender: UIButton) {
|
|
||||||
sender.isEnabled = false
|
|
||||||
app.makeIPCRequests()
|
|
||||||
sender.isEnabled = true
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
|
||||||
//NotificationCenter.default.addObserver(self, selector: #selector(TableViewController.VPNStatusDidChange(_:)), name: NSNotification.Name.NEVPNStatusDidChange, object: nil)
|
|
||||||
|
|
||||||
if let row = self.tableView.indexPathForSelectedRow {
|
|
||||||
self.tableView.deselectRow(at: row, animated: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
self.statsVersion.text = Yggdrasil.MobileGetVersion()
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewWillDisappear(_ animated: Bool) {
|
|
||||||
//NotificationCenter.default.removeObserver(self, name: NSNotification.Name.NEVPNStatusDidChange, object: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
|
||||||
self.onYggdrasilSelfUpdated(notification: NSNotification.init(name: NSNotification.Name.YggdrasilSettingsUpdated, object: nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewWillLayoutSubviews() {
|
|
||||||
self.onYggdrasilSelfUpdated(notification: NSNotification.init(name: NSNotification.Name.YggdrasilSettingsUpdated, object: nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
||||||
if let row = self.tableView.indexPathForSelectedRow {
|
|
||||||
self.tableView.deselectRow(at: row, animated: true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func onYggdrasilSettingsUpdated(notification: NSNotification) {
|
|
||||||
toggleLabel.isEnabled = !app.vpnManager.isOnDemandEnabled
|
|
||||||
toggleConnect.isEnabled = !app.vpnManager.isOnDemandEnabled
|
|
||||||
|
|
||||||
if let footer = toggleTableView.footerView(forSection: 0) {
|
|
||||||
if let label = footer.textLabel {
|
|
||||||
label.text = app.vpnManager.isOnDemandEnabled ? "Yggdrasil is configured to automatically start and stop based on available connectivity." : "Yggdrasil is configured to start and stop manually."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateConnectedStatus() {
|
|
||||||
if self.app.vpnManager.connection.status == .connected {
|
|
||||||
if app.yggdrasilDHT.count > 0 {
|
|
||||||
connectedStatusLabel.text = "Enabled"
|
|
||||||
connectedStatusLabel.textColor = UIColor(red: 0.37, green: 0.79, blue: 0.35, alpha: 1.0)
|
|
||||||
} else {
|
|
||||||
connectedStatusLabel.text = "No connectivity"
|
|
||||||
connectedStatusLabel.textColor = UIColor.red
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
connectedStatusLabel.text = "Not enabled"
|
|
||||||
connectedStatusLabel.textColor = UIColor.systemGray
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override func didReceiveMemoryWarning() {
|
|
||||||
super.didReceiveMemoryWarning()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func onYggdrasilSelfUpdated(notification: NSNotification) {
|
|
||||||
statsSelfIP.text = app.yggdrasilIP
|
|
||||||
statsSelfSubnet.text = app.yggdrasilSubnet
|
|
||||||
statsSelfCoords.text = app.yggdrasilCoords
|
|
||||||
|
|
||||||
statsSelfIPCell.layoutSubviews()
|
|
||||||
statsSelfSubnetCell.layoutSubviews()
|
|
||||||
statsSelfCoordsCell.layoutSubviews()
|
|
||||||
|
|
||||||
let status = self.app.vpnManager.connection.status
|
|
||||||
toggleConnect.isOn = status == .connecting || status == .connected
|
|
||||||
|
|
||||||
self.updateConnectedStatus()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func onYggdrasilDHTUpdated(notification: NSNotification) {
|
|
||||||
self.updateConnectedStatus()
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func onYggdrasilPeersUpdated(notification: NSNotification) {
|
|
||||||
let peercount = app.yggdrasilPeers.count
|
|
||||||
if peercount <= 0 {
|
|
||||||
statsSelfPeers.text = "No peers"
|
|
||||||
} else if peercount == 1 {
|
|
||||||
statsSelfPeers.text = "\(peercount) peer"
|
|
||||||
} else {
|
|
||||||
statsSelfPeers.text = "\(peercount) peers"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction func toggleVPNStatus(_ sender: UISwitch, forEvent event: UIEvent) {
|
|
||||||
if sender.isOn {
|
|
||||||
do {
|
|
||||||
try self.app.vpnManager.connection.startVPNTunnel()
|
|
||||||
} catch {
|
|
||||||
print(error)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.app.vpnManager.connection.stopVPNTunnel()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,72 +3,54 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 52;
|
objectVersion = 55;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
3913E9C021DD3A51001E0EC7 /* SplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3913E9BF21DD3A51001E0EC7 /* SplitViewController.swift */; };
|
|
||||||
391B72A82A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 391B72A62A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift */; };
|
391B72A82A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 391B72A62A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift */; };
|
||||||
3939196B21E35A7C009320F3 /* PeersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3939196A21E35A7C009320F3 /* PeersViewController.swift */; };
|
|
||||||
3939196D21E39313009320F3 /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3939196C21E39313009320F3 /* UIDevice.swift */; };
|
|
||||||
3939197321E39815009320F3 /* ToggleTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3939197221E39815009320F3 /* ToggleTableViewCell.swift */; };
|
|
||||||
394A1EB321DEA46400D9F553 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 394A1EB221DEA46400D9F553 /* SettingsViewController.swift */; };
|
|
||||||
3952ADB729945AF700B3835D /* ConfigurationProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3952ADB629945AF700B3835D /* ConfigurationProxy.swift */; };
|
|
||||||
3952ADB829945AF700B3835D /* ConfigurationProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3952ADB629945AF700B3835D /* ConfigurationProxy.swift */; };
|
3952ADB829945AF700B3835D /* ConfigurationProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3952ADB629945AF700B3835D /* ConfigurationProxy.swift */; };
|
||||||
3952ADBA29945AFA00B3835D /* CrossPlatformAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3952ADB929945AFA00B3835D /* CrossPlatformAppDelegate.swift */; };
|
|
||||||
39682A392225AD15004FB670 /* CopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39682A382225AD15004FB670 /* CopyableLabel.swift */; };
|
|
||||||
3996AF38270328080070947D /* Yggdrasil.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3996AF37270328080070947D /* Yggdrasil.xcframework */; };
|
|
||||||
3996AF39270328080070947D /* Yggdrasil.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3996AF37270328080070947D /* Yggdrasil.xcframework */; };
|
3996AF39270328080070947D /* Yggdrasil.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3996AF37270328080070947D /* Yggdrasil.xcframework */; };
|
||||||
39AE88392319C93F0010FFF6 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 39AE88382319C93F0010FFF6 /* NetworkExtension.framework */; };
|
|
||||||
39B51A4A2997062E0059D29D /* PeersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39B51A492997062E0059D29D /* PeersView.swift */; };
|
39B51A4A2997062E0059D29D /* PeersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39B51A492997062E0059D29D /* PeersView.swift */; };
|
||||||
39B51A4B29994F240059D29D /* ConfigurationProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3952ADB629945AF700B3835D /* ConfigurationProxy.swift */; };
|
39B51A4B29994F240059D29D /* ConfigurationProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3952ADB629945AF700B3835D /* ConfigurationProxy.swift */; };
|
||||||
39B51A4C29994F350059D29D /* CrossPlatformAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3952ADB929945AFA00B3835D /* CrossPlatformAppDelegate.swift */; };
|
39B51A4C29994F350059D29D /* CrossPlatformAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3952ADB929945AFA00B3835D /* CrossPlatformAppDelegate.swift */; };
|
||||||
39B51A4D299951D60059D29D /* NSNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CC924B221DEDCE004960DC /* NSNotification.swift */; };
|
39B51A4D299951D60059D29D /* IPCResponses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CC924B221DEDCE004960DC /* IPCResponses.swift */; };
|
||||||
39BF9FC62A2F5FA7000E7269 /* PacketTunnelProvider+FileDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39BF9FC52A2F5FA7000E7269 /* PacketTunnelProvider+FileDescriptor.swift */; };
|
|
||||||
39BF9FC72A2F6FFD000E7269 /* Yggdrasil.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3996AF37270328080070947D /* Yggdrasil.xcframework */; };
|
39BF9FC72A2F6FFD000E7269 /* Yggdrasil.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3996AF37270328080070947D /* Yggdrasil.xcframework */; };
|
||||||
39CC924C221DEDCE004960DC /* NSNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CC924B221DEDCE004960DC /* NSNotification.swift */; };
|
39CC924D221DEDD3004960DC /* IPCResponses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CC924B221DEDCE004960DC /* IPCResponses.swift */; };
|
||||||
39CC924D221DEDD3004960DC /* NSNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CC924B221DEDCE004960DC /* NSNotification.swift */; };
|
|
||||||
39F0205E2996CD760093F603 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39F0205D2996CD760093F603 /* Application.swift */; };
|
39F0205E2996CD760093F603 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39F0205D2996CD760093F603 /* Application.swift */; };
|
||||||
39F020602996CD760093F603 /* StatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39F0205F2996CD760093F603 /* StatusView.swift */; };
|
39F020602996CD760093F603 /* StatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39F0205F2996CD760093F603 /* StatusView.swift */; };
|
||||||
39F020622996CD770093F603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 39F020612996CD770093F603 /* Assets.xcassets */; };
|
39F020622996CD770093F603 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 39F020612996CD770093F603 /* Assets.xcassets */; };
|
||||||
39F020662996CD770093F603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 39F020652996CD770093F603 /* Preview Assets.xcassets */; };
|
39F020662996CD770093F603 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 39F020652996CD770093F603 /* Preview Assets.xcassets */; };
|
||||||
39F0206B2996CF260093F603 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39F0206A2996CF260093F603 /* SettingsView.swift */; };
|
39F0206B2996CF260093F603 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39F0206A2996CF260093F603 /* SettingsView.swift */; };
|
||||||
E593CE6F1DF8FC3C00D7265D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E593CE6E1DF8FC3C00D7265D /* AppDelegate.swift */; };
|
39F99B342A48F6E50045BD10 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 39AE88382319C93F0010FFF6 /* NetworkExtension.framework */; };
|
||||||
E593CE711DF8FC3C00D7265D /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E593CE701DF8FC3C00D7265D /* TableViewController.swift */; };
|
39F99B382A48F74F0045BD10 /* YggdrasilNetworkExtension.appex in CopyFiles */ = {isa = PBXBuildFile; fileRef = E593CE971DF905AF00D7265D /* YggdrasilNetworkExtension.appex */; platformFilters = (ios, macos, ); settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
E593CE741DF8FC3C00D7265D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E593CE721DF8FC3C00D7265D /* Main.storyboard */; };
|
|
||||||
E593CE761DF8FC3C00D7265D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E593CE751DF8FC3C00D7265D /* Assets.xcassets */; };
|
|
||||||
E593CE791DF8FC3C00D7265D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E593CE771DF8FC3C00D7265D /* LaunchScreen.storyboard */; };
|
|
||||||
E593CE9C1DF905AF00D7265D /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E593CE9B1DF905AF00D7265D /* PacketTunnelProvider.swift */; };
|
E593CE9C1DF905AF00D7265D /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E593CE9B1DF905AF00D7265D /* PacketTunnelProvider.swift */; };
|
||||||
E593CEA01DF905AF00D7265D /* YggdrasilNetworkExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = E593CE971DF905AF00D7265D /* YggdrasilNetworkExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
E593CE9E1DF905AF00D7265D /* PBXContainerItemProxy */ = {
|
39F99B352A48F70F0045BD10 /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = E593CE631DF8FC3C00D7265D /* Project object */;
|
containerPortal = E593CE631DF8FC3C00D7265D /* Project object */;
|
||||||
proxyType = 1;
|
proxyType = 1;
|
||||||
remoteGlobalIDString = E593CE961DF905AF00D7265D;
|
remoteGlobalIDString = E593CE961DF905AF00D7265D;
|
||||||
remoteInfo = NEPacketTunnelVPNDemoTunnel;
|
remoteInfo = YggdrasilNetworkExtension;
|
||||||
};
|
};
|
||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
E593CEA41DF905B000D7265D /* Embed Foundation Extensions */ = {
|
39F99B372A48F7380045BD10 /* CopyFiles */ = {
|
||||||
isa = PBXCopyFilesBuildPhase;
|
isa = PBXCopyFilesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
dstPath = "";
|
dstPath = "";
|
||||||
dstSubfolderSpec = 13;
|
dstSubfolderSpec = 13;
|
||||||
files = (
|
files = (
|
||||||
E593CEA01DF905AF00D7265D /* YggdrasilNetworkExtension.appex in Embed Foundation Extensions */,
|
39F99B382A48F74F0045BD10 /* YggdrasilNetworkExtension.appex in CopyFiles */,
|
||||||
);
|
);
|
||||||
name = "Embed Foundation Extensions";
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
3913E99C21DB9B1C001E0EC7 /* YggdrasilNetworkExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = YggdrasilNetworkExtension.entitlements; sourceTree = "<group>"; };
|
3913E99C21DB9B1C001E0EC7 /* YggdrasilNetworkExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = YggdrasilNetworkExtension.entitlements; sourceTree = "<group>"; };
|
||||||
3913E99E21DB9B41001E0EC7 /* YggdrasilNetwork.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = YggdrasilNetwork.entitlements; sourceTree = "<group>"; };
|
|
||||||
3913E9BF21DD3A51001E0EC7 /* SplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitViewController.swift; sourceTree = "<group>"; };
|
3913E9BF21DD3A51001E0EC7 /* SplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitViewController.swift; sourceTree = "<group>"; };
|
||||||
391B72A52A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "PacketTunnelProvider+FileDescriptor.h"; sourceTree = "<group>"; };
|
391B72A52A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "PacketTunnelProvider+FileDescriptor.h"; sourceTree = "<group>"; };
|
||||||
391B72A62A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PacketTunnelProvider+FileDescriptor.swift"; sourceTree = "<group>"; };
|
391B72A62A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PacketTunnelProvider+FileDescriptor.swift"; sourceTree = "<group>"; };
|
||||||
|
@ -84,9 +66,7 @@
|
||||||
39AE88382319C93F0010FFF6 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; };
|
39AE88382319C93F0010FFF6 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; };
|
||||||
39B51A492997062E0059D29D /* PeersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeersView.swift; sourceTree = "<group>"; };
|
39B51A492997062E0059D29D /* PeersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeersView.swift; sourceTree = "<group>"; };
|
||||||
39BF9FC12A2E9E51000E7269 /* YggdrasilNetworkExtension-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "YggdrasilNetworkExtension-Bridging-Header.h"; sourceTree = "<group>"; };
|
39BF9FC12A2E9E51000E7269 /* YggdrasilNetworkExtension-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "YggdrasilNetworkExtension-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
39BF9FC22A2E9E52000E7269 /* PacketTunnelProvider+FileDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PacketTunnelProvider+FileDescriptor.h"; sourceTree = "<group>"; };
|
39CC924B221DEDCE004960DC /* IPCResponses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPCResponses.swift; sourceTree = "<group>"; };
|
||||||
39BF9FC52A2F5FA7000E7269 /* PacketTunnelProvider+FileDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PacketTunnelProvider+FileDescriptor.swift"; sourceTree = "<group>"; };
|
|
||||||
39CC924B221DEDCE004960DC /* NSNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSNotification.swift; sourceTree = "<group>"; };
|
|
||||||
39F0205B2996CD760093F603 /* YggdrasilSwiftUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = YggdrasilSwiftUI.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
39F0205B2996CD760093F603 /* YggdrasilSwiftUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = YggdrasilSwiftUI.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
39F0205D2996CD760093F603 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
|
39F0205D2996CD760093F603 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
|
||||||
39F0205F2996CD760093F603 /* StatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusView.swift; sourceTree = "<group>"; };
|
39F0205F2996CD760093F603 /* StatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusView.swift; sourceTree = "<group>"; };
|
||||||
|
@ -94,7 +74,6 @@
|
||||||
39F020632996CD770093F603 /* YggdrasilSwiftUI.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = YggdrasilSwiftUI.entitlements; sourceTree = "<group>"; };
|
39F020632996CD770093F603 /* YggdrasilSwiftUI.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = YggdrasilSwiftUI.entitlements; sourceTree = "<group>"; };
|
||||||
39F020652996CD770093F603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
39F020652996CD770093F603 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||||
39F0206A2996CF260093F603 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
|
39F0206A2996CF260093F603 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
|
||||||
E593CE6B1DF8FC3C00D7265D /* YggdrasilNetwork.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = YggdrasilNetwork.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
E593CE6E1DF8FC3C00D7265D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
E593CE6E1DF8FC3C00D7265D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
E593CE701DF8FC3C00D7265D /* TableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = "<group>"; };
|
E593CE701DF8FC3C00D7265D /* TableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = "<group>"; };
|
||||||
E593CE731DF8FC3C00D7265D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
E593CE731DF8FC3C00D7265D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||||
|
@ -111,19 +90,11 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
39F99B342A48F6E50045BD10 /* NetworkExtension.framework in Frameworks */,
|
||||||
39BF9FC72A2F6FFD000E7269 /* Yggdrasil.xcframework in Frameworks */,
|
39BF9FC72A2F6FFD000E7269 /* Yggdrasil.xcframework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
E593CE681DF8FC3C00D7265D /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
3996AF38270328080070947D /* Yggdrasil.xcframework in Frameworks */,
|
|
||||||
39AE88392319C93F0010FFF6 /* NetworkExtension.framework in Frameworks */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
E593CE941DF905AF00D7265D /* Frameworks */ = {
|
E593CE941DF905AF00D7265D /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -185,7 +156,7 @@
|
||||||
children = (
|
children = (
|
||||||
3952ADB929945AFA00B3835D /* CrossPlatformAppDelegate.swift */,
|
3952ADB929945AFA00B3835D /* CrossPlatformAppDelegate.swift */,
|
||||||
3952ADB629945AF700B3835D /* ConfigurationProxy.swift */,
|
3952ADB629945AF700B3835D /* ConfigurationProxy.swift */,
|
||||||
39CC924B221DEDCE004960DC /* NSNotification.swift */,
|
39CC924B221DEDCE004960DC /* IPCResponses.swift */,
|
||||||
);
|
);
|
||||||
name = "Yggdrasil Network Core";
|
name = "Yggdrasil Network Core";
|
||||||
path = "Yggdrasil Network Cross-Platform";
|
path = "Yggdrasil Network Cross-Platform";
|
||||||
|
@ -226,8 +197,6 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
3952ADB529945AE900B3835D /* Yggdrasil Network Core */,
|
3952ADB529945AE900B3835D /* Yggdrasil Network Core */,
|
||||||
3913E99E21DB9B41001E0EC7 /* YggdrasilNetwork.entitlements */,
|
|
||||||
3913E99C21DB9B1C001E0EC7 /* YggdrasilNetworkExtension.entitlements */,
|
|
||||||
E593CE981DF905AF00D7265D /* Yggdrasil Network Extension */,
|
E593CE981DF905AF00D7265D /* Yggdrasil Network Extension */,
|
||||||
E593CE6D1DF8FC3C00D7265D /* Yggdrasil Network iOS */,
|
E593CE6D1DF8FC3C00D7265D /* Yggdrasil Network iOS */,
|
||||||
39F0205C2996CD760093F603 /* YggdrasilSwiftUI */,
|
39F0205C2996CD760093F603 /* YggdrasilSwiftUI */,
|
||||||
|
@ -239,7 +208,6 @@
|
||||||
E593CE6C1DF8FC3C00D7265D /* Products */ = {
|
E593CE6C1DF8FC3C00D7265D /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
E593CE6B1DF8FC3C00D7265D /* YggdrasilNetwork.app */,
|
|
||||||
E593CE971DF905AF00D7265D /* YggdrasilNetworkExtension.appex */,
|
E593CE971DF905AF00D7265D /* YggdrasilNetworkExtension.appex */,
|
||||||
39F0205B2996CD760093F603 /* YggdrasilSwiftUI.app */,
|
39F0205B2996CD760093F603 /* YggdrasilSwiftUI.app */,
|
||||||
);
|
);
|
||||||
|
@ -266,6 +234,7 @@
|
||||||
E593CE9B1DF905AF00D7265D /* PacketTunnelProvider.swift */,
|
E593CE9B1DF905AF00D7265D /* PacketTunnelProvider.swift */,
|
||||||
391B72A52A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.h */,
|
391B72A52A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.h */,
|
||||||
391B72A62A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift */,
|
391B72A62A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift */,
|
||||||
|
3913E99C21DB9B1C001E0EC7 /* YggdrasilNetworkExtension.entitlements */,
|
||||||
391B72A72A2FD90100896278 /* YggdrasilNetworkExtension-Bridging-Header.h */,
|
391B72A72A2FD90100896278 /* YggdrasilNetworkExtension-Bridging-Header.h */,
|
||||||
E593CE9D1DF905AF00D7265D /* Info.plist */,
|
E593CE9D1DF905AF00D7265D /* Info.plist */,
|
||||||
39BF9FC12A2E9E51000E7269 /* YggdrasilNetworkExtension-Bridging-Header.h */,
|
39BF9FC12A2E9E51000E7269 /* YggdrasilNetworkExtension-Bridging-Header.h */,
|
||||||
|
@ -283,35 +252,18 @@
|
||||||
39F020572996CD760093F603 /* Sources */,
|
39F020572996CD760093F603 /* Sources */,
|
||||||
39F020582996CD760093F603 /* Frameworks */,
|
39F020582996CD760093F603 /* Frameworks */,
|
||||||
39F020592996CD760093F603 /* Resources */,
|
39F020592996CD760093F603 /* Resources */,
|
||||||
|
39F99B372A48F7380045BD10 /* CopyFiles */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
|
39F99B362A48F70F0045BD10 /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
name = YggdrasilSwiftUI;
|
name = YggdrasilSwiftUI;
|
||||||
productName = YggdrasilSwiftUI;
|
productName = YggdrasilSwiftUI;
|
||||||
productReference = 39F0205B2996CD760093F603 /* YggdrasilSwiftUI.app */;
|
productReference = 39F0205B2996CD760093F603 /* YggdrasilSwiftUI.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
E593CE6A1DF8FC3C00D7265D /* YggdrasilNetwork */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = E593CE7D1DF8FC3C00D7265D /* Build configuration list for PBXNativeTarget "YggdrasilNetwork" */;
|
|
||||||
buildPhases = (
|
|
||||||
E593CE671DF8FC3C00D7265D /* Sources */,
|
|
||||||
E593CE681DF8FC3C00D7265D /* Frameworks */,
|
|
||||||
E593CE691DF8FC3C00D7265D /* Resources */,
|
|
||||||
E593CEA41DF905B000D7265D /* Embed Foundation Extensions */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
E593CE9F1DF905AF00D7265D /* PBXTargetDependency */,
|
|
||||||
);
|
|
||||||
name = YggdrasilNetwork;
|
|
||||||
productName = NEPacketTunnelVPNDemo;
|
|
||||||
productReference = E593CE6B1DF8FC3C00D7265D /* YggdrasilNetwork.app */;
|
|
||||||
productType = "com.apple.product-type.application";
|
|
||||||
};
|
|
||||||
E593CE961DF905AF00D7265D /* YggdrasilNetworkExtension */ = {
|
E593CE961DF905AF00D7265D /* YggdrasilNetworkExtension */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = E593CEA31DF905AF00D7265D /* Build configuration list for PBXNativeTarget "YggdrasilNetworkExtension" */;
|
buildConfigurationList = E593CEA31DF905AF00D7265D /* Build configuration list for PBXNativeTarget "YggdrasilNetworkExtension" */;
|
||||||
|
@ -335,31 +287,14 @@
|
||||||
E593CE631DF8FC3C00D7265D /* Project object */ = {
|
E593CE631DF8FC3C00D7265D /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
|
BuildIndependentTargetsInParallel = YES;
|
||||||
LastSwiftUpdateCheck = 1420;
|
LastSwiftUpdateCheck = 1420;
|
||||||
LastUpgradeCheck = 1420;
|
LastUpgradeCheck = 1430;
|
||||||
ORGANIZATIONNAME = "";
|
ORGANIZATIONNAME = "";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
39F0205A2996CD760093F603 = {
|
39F0205A2996CD760093F603 = {
|
||||||
CreatedOnToolsVersion = 14.2;
|
CreatedOnToolsVersion = 14.2;
|
||||||
};
|
};
|
||||||
E593CE6A1DF8FC3C00D7265D = {
|
|
||||||
CreatedOnToolsVersion = 8.1;
|
|
||||||
LastSwiftMigration = 1030;
|
|
||||||
SystemCapabilities = {
|
|
||||||
com.apple.ApplicationGroups.iOS = {
|
|
||||||
enabled = 1;
|
|
||||||
};
|
|
||||||
com.apple.NetworkExtensions.iOS = {
|
|
||||||
enabled = 1;
|
|
||||||
};
|
|
||||||
com.apple.VPNLite = {
|
|
||||||
enabled = 1;
|
|
||||||
};
|
|
||||||
com.apple.iCloud = {
|
|
||||||
enabled = 0;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
E593CE961DF905AF00D7265D = {
|
E593CE961DF905AF00D7265D = {
|
||||||
CreatedOnToolsVersion = 8.1;
|
CreatedOnToolsVersion = 8.1;
|
||||||
LastSwiftMigration = 1430;
|
LastSwiftMigration = 1430;
|
||||||
|
@ -390,7 +325,6 @@
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
E593CE6A1DF8FC3C00D7265D /* YggdrasilNetwork */,
|
|
||||||
E593CE961DF905AF00D7265D /* YggdrasilNetworkExtension */,
|
E593CE961DF905AF00D7265D /* YggdrasilNetworkExtension */,
|
||||||
39F0205A2996CD760093F603 /* YggdrasilSwiftUI */,
|
39F0205A2996CD760093F603 /* YggdrasilSwiftUI */,
|
||||||
);
|
);
|
||||||
|
@ -407,16 +341,6 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
E593CE691DF8FC3C00D7265D /* Resources */ = {
|
|
||||||
isa = PBXResourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
E593CE791DF8FC3C00D7265D /* LaunchScreen.storyboard in Resources */,
|
|
||||||
E593CE761DF8FC3C00D7265D /* Assets.xcassets in Resources */,
|
|
||||||
E593CE741DF8FC3C00D7265D /* Main.storyboard in Resources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
E593CE951DF905AF00D7265D /* Resources */ = {
|
E593CE951DF905AF00D7265D /* Resources */ = {
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -435,35 +359,17 @@
|
||||||
39F0206B2996CF260093F603 /* SettingsView.swift in Sources */,
|
39F0206B2996CF260093F603 /* SettingsView.swift in Sources */,
|
||||||
39B51A4A2997062E0059D29D /* PeersView.swift in Sources */,
|
39B51A4A2997062E0059D29D /* PeersView.swift in Sources */,
|
||||||
39F020602996CD760093F603 /* StatusView.swift in Sources */,
|
39F020602996CD760093F603 /* StatusView.swift in Sources */,
|
||||||
39B51A4D299951D60059D29D /* NSNotification.swift in Sources */,
|
39B51A4D299951D60059D29D /* IPCResponses.swift in Sources */,
|
||||||
39B51A4C29994F350059D29D /* CrossPlatformAppDelegate.swift in Sources */,
|
39B51A4C29994F350059D29D /* CrossPlatformAppDelegate.swift in Sources */,
|
||||||
39F0205E2996CD760093F603 /* Application.swift in Sources */,
|
39F0205E2996CD760093F603 /* Application.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
E593CE671DF8FC3C00D7265D /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
3939196B21E35A7C009320F3 /* PeersViewController.swift in Sources */,
|
|
||||||
3939197321E39815009320F3 /* ToggleTableViewCell.swift in Sources */,
|
|
||||||
3939196D21E39313009320F3 /* UIDevice.swift in Sources */,
|
|
||||||
394A1EB321DEA46400D9F553 /* SettingsViewController.swift in Sources */,
|
|
||||||
E593CE711DF8FC3C00D7265D /* TableViewController.swift in Sources */,
|
|
||||||
3952ADBA29945AFA00B3835D /* CrossPlatformAppDelegate.swift in Sources */,
|
|
||||||
3952ADB729945AF700B3835D /* ConfigurationProxy.swift in Sources */,
|
|
||||||
39682A392225AD15004FB670 /* CopyableLabel.swift in Sources */,
|
|
||||||
E593CE6F1DF8FC3C00D7265D /* AppDelegate.swift in Sources */,
|
|
||||||
3913E9C021DD3A51001E0EC7 /* SplitViewController.swift in Sources */,
|
|
||||||
39CC924C221DEDCE004960DC /* NSNotification.swift in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
E593CE931DF905AF00D7265D /* Sources */ = {
|
E593CE931DF905AF00D7265D /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
39CC924D221DEDD3004960DC /* NSNotification.swift in Sources */,
|
39CC924D221DEDD3004960DC /* IPCResponses.swift in Sources */,
|
||||||
E593CE9C1DF905AF00D7265D /* PacketTunnelProvider.swift in Sources */,
|
E593CE9C1DF905AF00D7265D /* PacketTunnelProvider.swift in Sources */,
|
||||||
3952ADB829945AF700B3835D /* ConfigurationProxy.swift in Sources */,
|
3952ADB829945AF700B3835D /* ConfigurationProxy.swift in Sources */,
|
||||||
391B72A82A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift in Sources */,
|
391B72A82A2FD90100896278 /* PacketTunnelProvider+FileDescriptor.swift in Sources */,
|
||||||
|
@ -473,10 +379,14 @@
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
/* Begin PBXTargetDependency section */
|
||||||
E593CE9F1DF905AF00D7265D /* PBXTargetDependency */ = {
|
39F99B362A48F70F0045BD10 /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
|
platformFilters = (
|
||||||
|
ios,
|
||||||
|
macos,
|
||||||
|
);
|
||||||
target = E593CE961DF905AF00D7265D /* YggdrasilNetworkExtension */;
|
target = E593CE961DF905AF00D7265D /* YggdrasilNetworkExtension */;
|
||||||
targetProxy = E593CE9E1DF905AF00D7265D /* PBXContainerItemProxy */;
|
targetProxy = 39F99B352A48F70F0045BD10 /* PBXContainerItemProxy */;
|
||||||
};
|
};
|
||||||
/* End PBXTargetDependency section */
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
|
@ -505,6 +415,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
@ -512,12 +423,14 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = YggdrasilSwiftUI/YggdrasilSwiftUI.entitlements;
|
CODE_SIGN_ENTITLEMENTS = YggdrasilSwiftUI/YggdrasilSwiftUI.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"YggdrasilSwiftUI/Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"YggdrasilSwiftUI/Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = R9AV23TXF2;
|
DEVELOPMENT_TEAM = R9AV23TXF2;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = Yggdrasil;
|
||||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
||||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
|
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
|
||||||
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
|
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
|
||||||
|
@ -535,13 +448,16 @@
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil.YggdrasilSwiftUI;
|
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = auto;
|
SDKROOT = auto;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
|
||||||
|
SUPPORTS_MACCATALYST = NO;
|
||||||
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
TVOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
@ -550,6 +466,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
@ -557,12 +474,14 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = YggdrasilSwiftUI/YggdrasilSwiftUI.entitlements;
|
CODE_SIGN_ENTITLEMENTS = YggdrasilSwiftUI/YggdrasilSwiftUI.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"YggdrasilSwiftUI/Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"YggdrasilSwiftUI/Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = R9AV23TXF2;
|
DEVELOPMENT_TEAM = R9AV23TXF2;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = Yggdrasil;
|
||||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
||||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
|
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
|
||||||
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
|
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
|
||||||
|
@ -579,13 +498,16 @@
|
||||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil.YggdrasilSwiftUI;
|
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = auto;
|
SDKROOT = auto;
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
|
||||||
|
SUPPORTS_MACCATALYST = NO;
|
||||||
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
TVOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
@ -711,72 +633,6 @@
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
E593CE7E1DF8FC3C00D7265D /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_ENTITLEMENTS = YggdrasilNetwork.entitlements;
|
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
|
||||||
CODE_SIGN_STYLE = Automatic;
|
|
||||||
CURRENT_PROJECT_VERSION = 32;
|
|
||||||
DEVELOPMENT_TEAM = R9AV23TXF2;
|
|
||||||
ENABLE_BITCODE = NO;
|
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"$(PROJECT_DIR)",
|
|
||||||
);
|
|
||||||
INFOPLIST_FILE = "$(SRCROOT)/Yggdrasil Network iOS/Info.plist";
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"@executable_path/Frameworks",
|
|
||||||
);
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
|
||||||
STRIP_INSTALLED_PRODUCT = NO;
|
|
||||||
SUPPORTS_MACCATALYST = NO;
|
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
E593CE7F1DF8FC3C00D7265D /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CODE_SIGN_ENTITLEMENTS = YggdrasilNetwork.entitlements;
|
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
|
||||||
CODE_SIGN_STYLE = Automatic;
|
|
||||||
CURRENT_PROJECT_VERSION = 32;
|
|
||||||
DEVELOPMENT_TEAM = R9AV23TXF2;
|
|
||||||
ENABLE_BITCODE = NO;
|
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"$(PROJECT_DIR)",
|
|
||||||
);
|
|
||||||
INFOPLIST_FILE = "$(SRCROOT)/Yggdrasil Network iOS/Info.plist";
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"@executable_path/Frameworks",
|
|
||||||
);
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
|
||||||
SUPPORTS_MACCATALYST = NO;
|
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "";
|
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
E593CEA11DF905AF00D7265D /* Debug */ = {
|
E593CEA11DF905AF00D7265D /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
@ -801,7 +657,6 @@
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil.extension;
|
PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil.extension;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
STRIP_INSTALLED_PRODUCT = NO;
|
|
||||||
SUPPORTS_MACCATALYST = YES;
|
SUPPORTS_MACCATALYST = YES;
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Yggdrasil Network Extension/YggdrasilNetworkExtension-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Yggdrasil Network Extension/YggdrasilNetworkExtension-Bridging-Header.h";
|
||||||
|
@ -864,15 +719,6 @@
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
E593CE7D1DF8FC3C00D7265D /* Build configuration list for PBXNativeTarget "YggdrasilNetwork" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
E593CE7E1DF8FC3C00D7265D /* Debug */,
|
|
||||||
E593CE7F1DF8FC3C00D7265D /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
E593CEA31DF905AF00D7265D /* Build configuration list for PBXNativeTarget "YggdrasilNetworkExtension" */ = {
|
E593CEA31DF905AF00D7265D /* Build configuration list for PBXNativeTarget "YggdrasilNetworkExtension" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1420"
|
LastUpgradeVersion = "1430"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1420"
|
LastUpgradeVersion = "1430"
|
||||||
wasCreatedForAppExtension = "YES"
|
wasCreatedForAppExtension = "YES"
|
||||||
version = "2.0">
|
version = "2.0">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
|
@ -84,7 +84,6 @@
|
||||||
savedToolIdentifier = ""
|
savedToolIdentifier = ""
|
||||||
useCustomWorkingDirectory = "NO"
|
useCustomWorkingDirectory = "NO"
|
||||||
debugDocumentVersioning = "YES"
|
debugDocumentVersioning = "YES"
|
||||||
askForAppToLaunch = "Yes"
|
|
||||||
launchAutomaticallySubstyle = "2">
|
launchAutomaticallySubstyle = "2">
|
||||||
<BuildableProductRunnable
|
<BuildableProductRunnable
|
||||||
runnableDebuggingMode = "0">
|
runnableDebuggingMode = "0">
|
||||||
|
|
68
Yggdrasil.xcframework/Info.plist
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>AvailableLibraries</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>macos-arm64_x86_64</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>Yggdrasil.framework</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
<string>x86_64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>macos</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>ios-arm64_x86_64-maccatalyst</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>Yggdrasil.framework</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
<string>x86_64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>ios</string>
|
||||||
|
<key>SupportedPlatformVariant</key>
|
||||||
|
<string>maccatalyst</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>ios-arm64</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>Yggdrasil.framework</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>ios</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>ios-arm64_x86_64-simulator</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>Yggdrasil.framework</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
<string>x86_64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>ios</string>
|
||||||
|
<key>SupportedPlatformVariant</key>
|
||||||
|
<string>simulator</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>XFWK</string>
|
||||||
|
<key>XCFrameworkFormatVersion</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -1,22 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>com.apple.developer.networking.networkextension</key>
|
|
||||||
<array>
|
|
||||||
<string>packet-tunnel-provider</string>
|
|
||||||
</array>
|
|
||||||
<key>com.apple.developer.networking.vpn.api</key>
|
|
||||||
<array>
|
|
||||||
<string>allow-vpn</string>
|
|
||||||
</array>
|
|
||||||
<key>com.apple.security.app-sandbox</key>
|
|
||||||
<true/>
|
|
||||||
<key>com.apple.security.application-groups</key>
|
|
||||||
<array>
|
|
||||||
<string>group.eu.neilalexander.yggdrasil</string>
|
|
||||||
</array>
|
|
||||||
<key>com.apple.security.network.client</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
|
@ -10,20 +10,21 @@ import NetworkExtension
|
||||||
|
|
||||||
@main
|
@main
|
||||||
struct Application: App {
|
struct Application: App {
|
||||||
|
@State private var selection: String? = "Status"
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
@UIApplicationDelegateAdaptor(CrossPlatformAppDelegate.self) static var appDelegate: CrossPlatformAppDelegate
|
@UIApplicationDelegateAdaptor(CrossPlatformAppDelegate.self) static var appDelegate: CrossPlatformAppDelegate
|
||||||
#elseif os(macOS)
|
#elseif os(macOS)
|
||||||
@NSApplicationDelegateAdaptor(CrossPlatformAppDelegate.self) static var appDelegate: CrossPlatformAppDelegate
|
@NSApplicationDelegateAdaptor(CrossPlatformAppDelegate.self) static var appDelegate: CrossPlatformAppDelegate
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@State private var selection: String? = "Status"
|
@Environment(\.scenePhase) var scenePhase
|
||||||
@State private var config: ConfigurationProxy = ConfigurationProxy()
|
|
||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
WindowGroup {
|
WindowGroup {
|
||||||
NavigationSplitView {
|
NavigationSplitView {
|
||||||
List(selection: $selection) {
|
List(selection: $selection) {
|
||||||
NavigationLink(destination: StatusView(yggdrasilConfiguration: $config)) {
|
NavigationLink(destination: StatusView()) {
|
||||||
HStack {
|
HStack {
|
||||||
Image(systemName: "info.circle")
|
Image(systemName: "info.circle")
|
||||||
.foregroundColor(.accentColor)
|
.foregroundColor(.accentColor)
|
||||||
|
@ -50,11 +51,30 @@ struct Application: App {
|
||||||
}
|
}
|
||||||
.listStyle(.sidebar)
|
.listStyle(.sidebar)
|
||||||
.navigationSplitViewColumnWidth(200)
|
.navigationSplitViewColumnWidth(200)
|
||||||
|
|
||||||
|
Image("YggdrasilLogo")
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fit)
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
.opacity(0.1)
|
||||||
|
.padding(.all, 24.0)
|
||||||
} detail: {
|
} detail: {
|
||||||
StatusView(yggdrasilConfiguration: $config)
|
StatusView()
|
||||||
}
|
}
|
||||||
.navigationTitle("Yggdrasil")
|
.navigationTitle("Yggdrasil")
|
||||||
.navigationSplitViewStyle(.automatic)
|
.navigationSplitViewStyle(.automatic)
|
||||||
|
.onChange(of: scenePhase) { phase in
|
||||||
|
switch phase {
|
||||||
|
case .background:
|
||||||
|
Application.appDelegate.becameBackground()
|
||||||
|
case .inactive:
|
||||||
|
Application.appDelegate.becameInactive()
|
||||||
|
case .active:
|
||||||
|
Application.appDelegate.becameActive()
|
||||||
|
@unknown default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
.windowStyle(.hiddenTitleBar)
|
.windowStyle(.hiddenTitleBar)
|
||||||
|
|
|
@ -1,6 +1,33 @@
|
||||||
{
|
{
|
||||||
"colors" : [
|
"colors" : [
|
||||||
{
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "display-p3",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.522",
|
||||||
|
"green" : "0.656",
|
||||||
|
"red" : "0.370"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "display-p3",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.718",
|
||||||
|
"green" : "0.896",
|
||||||
|
"red" : "0.514"
|
||||||
|
}
|
||||||
|
},
|
||||||
"idiom" : "universal"
|
"idiom" : "universal"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"scale" : "2x",
|
|
||||||
"size" : "20x20"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"scale" : "3x",
|
|
||||||
"size" : "20x20"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"scale" : "2x",
|
|
||||||
"size" : "29x29"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"scale" : "3x",
|
|
||||||
"size" : "29x29"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"scale" : "2x",
|
|
||||||
"size" : "40x40"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"scale" : "3x",
|
|
||||||
"size" : "40x40"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename" : "drawing copy-1.png",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"scale" : "2x",
|
|
||||||
"size" : "60x60"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename" : "drawing copy.png",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"scale" : "3x",
|
|
||||||
"size" : "60x60"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"scale" : "1x",
|
|
||||||
"size" : "20x20"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"scale" : "2x",
|
|
||||||
"size" : "20x20"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"scale" : "1x",
|
|
||||||
"size" : "29x29"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"scale" : "2x",
|
|
||||||
"size" : "29x29"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"scale" : "1x",
|
|
||||||
"size" : "40x40"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"scale" : "2x",
|
|
||||||
"size" : "40x40"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename" : "drawing copy-2.png",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"scale" : "1x",
|
|
||||||
"size" : "76x76"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename" : "drawing copy-3.png",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"scale" : "2x",
|
|
||||||
"size" : "76x76"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename" : "drawing copy-5.png",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"scale" : "2x",
|
|
||||||
"size" : "83.5x83.5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename" : "drawing copy-4.png",
|
|
||||||
"idiom" : "ios-marketing",
|
|
||||||
"scale" : "1x",
|
|
||||||
"size" : "1024x1024"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4 KiB |
|
@ -1,58 +1,73 @@
|
||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "drawing copy-4 1.png",
|
"filename" : "icon_512x512@2x 1.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"platform" : "ios",
|
"platform" : "ios",
|
||||||
"size" : "1024x1024"
|
"size" : "1024x1024"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename" : "icon-1024.png",
|
||||||
|
"idiom" : "ios-marketing",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "1024x1024"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "icon_16x16.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "16x16"
|
"size" : "16x16"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename" : "icon_16x16@2x.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "16x16"
|
"size" : "16x16"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename" : "icon_32x32.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "32x32"
|
"size" : "32x32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename" : "icon_32x32@2x.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "32x32"
|
"size" : "32x32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename" : "icon_128x128.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "128x128"
|
"size" : "128x128"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename" : "icon_128x128@2x.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "128x128"
|
"size" : "128x128"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename" : "icon_256x256.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "256x256"
|
"size" : "256x256"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename" : "icon_256x256@2x.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "256x256"
|
"size" : "256x256"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename" : "icon_512x512 1.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "512x512"
|
"size" : "512x512"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "drawing copy-4.png",
|
"filename" : "icon_512x512@2x.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "512x512"
|
"size" : "512x512"
|
||||||
|
|
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 624 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 73 KiB |
27
YggdrasilSwiftUI/Assets.xcassets/YggdrasilLogo.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "ygg-neilalexander.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "ygg-neilalexander 1.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "ygg-neilalexander 2.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"preserves-vector-representation" : true,
|
||||||
|
"template-rendering-intent" : "template"
|
||||||
|
}
|
||||||
|
}
|
157
YggdrasilSwiftUI/Assets.xcassets/YggdrasilLogo.imageset/ygg-neilalexander 1.svg
vendored
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
sodipodi:docname="drawing.svg"
|
||||||
|
inkscape:version="0.91 r13725"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4240"
|
||||||
|
viewBox="0 0 981.96461 321.60015"
|
||||||
|
height="90.762711mm"
|
||||||
|
width="277.13223mm">
|
||||||
|
<defs
|
||||||
|
id="defs4242" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-top="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="1"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="1021"
|
||||||
|
inkscape:window-width="2048"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:current-layer="layer2"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:cy="13.914395"
|
||||||
|
inkscape:cx="751.6295"
|
||||||
|
inkscape:zoom="0.66468037"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
id="base" />
|
||||||
|
<metadata
|
||||||
|
id="metadata4245">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(383.92494,-160.49328)" />
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer2"
|
||||||
|
inkscape:label="Layer 2"
|
||||||
|
transform="translate(383.92494,-160.49328)">
|
||||||
|
<path
|
||||||
|
style="fill:#000000"
|
||||||
|
d="m 352.74397,478.24119 c 0.92103,-3.76903 11.87131,-30.48993 21.5083,-52.48465 9.86344,-22.51152 9.67726,-21.6278 6.92943,-32.89221 -3.42997,-14.06075 -3.22164,-36.95243 0.44688,-49.10642 13.24423,-43.87864 47.63362,-73.61698 122.30718,-105.76556 24.32504,-10.47245 37.67777,-17.18807 47.80968,-24.04538 17.86083,-12.08828 36.4402,-33.06424 42.38057,-47.84736 1.25285,-3.11781 2.66096,-5.64051 3.12912,-5.60598 1.46014,0.10767 0.73701,44.30167 -0.9768,59.69719 -10.61597,95.36545 -42.95689,157.39345 -96.20598,184.51751 -30.73114,15.65385 -79.17559,21.45357 -101.74118,12.18037 -3.19081,-1.31125 -6.5492,-2.38408 -7.46311,-2.38408 -3.43636,0 -15.75824,32.89925 -19.29523,51.51802 -1.09802,5.78003 -2.76237,13.70787 -3.00898,14.91667 -5.50064,-0.0422 -0.35371,-0.0119 -8.18026,-0.0119 l -8.29605,0 z"
|
||||||
|
id="path4918"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ssssssscssssscscs" />
|
||||||
|
<g
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:150px;line-height:86.00000143%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
id="text4920"
|
||||||
|
transform="translate(-2,0)">
|
||||||
|
<path
|
||||||
|
d="m -345.34994,319.70594 -36.575,-55.6875 21.725,0 23.925,38.775 24.2,-38.775 20.625,0 -36.575,55.6875 0,41.6625 -17.325,0 0,-41.6625 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5638"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -202.55678,354.21844 q -18.0125,9.625 -40.2875,9.625 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.1375,0 20.9,2.75 9.7625,2.6125 17.4625,9.4875 l -12.7875,12.925 q -4.675,-4.5375 -11.4125,-7.0125 -6.6,-2.475 -14.025,-2.475 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 6.6,0 12.375,-1.2375 5.9125,-1.2375 10.45,-3.85 l 0,-22.9625 -19.9375,0 0,-15.675 37.2625,0 0,49.775 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5640"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -102.05346,354.21844 q -18.0125,9.625 -40.2875,9.625 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.1375,0 20.9,2.75 9.7625,2.6125 17.4625,9.4875 l -12.7875,12.925 q -4.675,-4.5375 -11.4125,-7.0125 -6.6,-2.475 -14.025,-2.475 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 6.6,0 12.375,-1.2375 5.9125,-1.2375 10.45,-3.85 l 0,-22.9625 -19.9375,0 0,-15.675 37.2625,0 0,49.775 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5642"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -90.037646,264.01844 38.3625,0 q 9.625,0 18.5625,3.025 8.9375,2.8875 15.8125,8.9375 6.875,6.05 11,15.2625 4.125,9.075 4.125,21.45 0,12.5125 -4.8125,21.725 -4.675,9.075 -12.2375,15.125 -7.425,5.9125 -16.6375,8.9375 -9.075,2.8875 -17.875,2.8875 l -36.3,0 0,-97.35 z m 30.25,81.675 q 8.1125,0 15.2625,-1.7875 7.2875,-1.925 12.65,-5.775 5.3625,-3.9875 8.3875,-10.175 3.1625,-6.325 3.1625,-15.2625 0,-8.8 -2.75,-15.125 -2.75,-6.325 -7.7,-10.175 -4.8125,-3.9875 -11.55,-5.775 -6.6,-1.925 -14.575,-1.925 l -15.8125,0 0,66 12.925,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5644"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 7.511578,264.01844 33.825,0 q 7.0125,0 13.475,1.375 6.6,1.2375 11.687502,4.4 5.0875,3.1625 8.1125,8.525 3.025,5.3625 3.025,13.6125 0,10.5875 -5.9125,17.7375 -5.775002,7.15 -16.637502,8.6625 l 25.850002,43.0375 -20.900002,0 -22.55,-41.25 -12.65,0 0,41.25 -17.325,0 0,-97.35 z m 30.8,41.25 q 3.7125,0 7.425,-0.275 3.7125,-0.4125 6.7375,-1.65 3.1625,-1.375 5.0875,-3.9875 1.925,-2.75 1.925,-7.5625 0,-4.2625 -1.7875,-6.875 -1.7875,-2.6125 -4.675,-3.85 -2.8875,-1.375 -6.4625,-1.7875 -3.4375,-0.4125 -6.7375,-0.4125 l -14.9875,0 0,26.4 13.475,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5646"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 126.82369,264.01844 14.9875,0 41.9375,97.35 -19.8,0 -9.075,-22.275 -42.2125,0 -8.8,22.275 -19.3875,0 42.35,-97.35 z m 22,60.225 -14.9875,-39.6 -15.2625,39.6 30.25,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5648"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 239.7639,284.91844 q -2.75,-3.9875 -7.425,-5.775 -4.5375,-1.925 -9.625,-1.925 -3.025,0 -5.9125,0.6875 -2.75,0.6875 -5.0875,2.2 -2.2,1.5125 -3.575,3.9875 -1.375,2.3375 -1.375,5.6375 0,4.95 3.4375,7.5625 3.4375,2.6125 8.525,4.5375 5.0875,1.925 11.1375,3.7125 6.05,1.7875 11.1375,4.95 5.0875,3.1625 8.525,8.3875 3.4375,5.225 3.4375,13.8875 0,7.8375 -2.8875,13.75 -2.8875,5.775 -7.8375,9.625 -4.8125,3.85 -11.275,5.775 -6.4625,1.925 -13.6125,1.925 -9.075,0 -17.4625,-3.025 -8.3875,-3.025 -14.4375,-10.175 l 13.0625,-12.65 q 3.1625,4.8125 8.25,7.5625 5.225,2.6125 11,2.6125 3.025,0 6.05,-0.825 3.025,-0.825 5.5,-2.475 2.475,-1.65 3.9875,-4.125 1.5125,-2.6125 1.5125,-5.9125 0,-5.3625 -3.4375,-8.25 -3.4375,-2.8875 -8.525,-4.8125 -5.0875,-2.0625 -11.1375,-3.85 -6.05,-1.7875 -11.1375,-4.8125 -5.0875,-3.1625 -8.525,-8.25 -3.4375,-5.225 -3.4375,-13.8875 0,-7.5625 3.025,-13.0625 3.1625,-5.5 8.1125,-9.075 5.0875,-3.7125 11.55,-5.5 6.4625,-1.7875 13.2,-1.7875 7.7,0 14.85,2.3375 7.2875,2.3375 13.0625,7.7 l -12.65,13.3375 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5650"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 264.21257,264.01844 17.325,0 0,97.35 -17.325,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5652"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 296.37837,264.01844 17.325,0 0,81.675 41.3875,0 0,15.675 -58.7125,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5654"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -369.13744,382.26844 22.9625,0 47.1625,72.325 0.275,0 0,-72.325 17.325,0 0,97.35 -22,0 -48.125,-74.6625 -0.275,0 0,74.6625 -17.325,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5656"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -270.48568,382.26844 64.4875,0 0,15.675 -47.1625,0 0,23.925 44.6875,0 0,15.675 -44.6875,0 0,26.4 49.6375,0 0,15.675 -66.9625,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5658"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -165.14057,397.94344 -29.8375,0 0,-15.675 77,0 0,15.675 -29.8375,0 0,81.675 -17.325,0 0,-81.675 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5660"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -111.36694,382.26844 18.974997,0 18.2875,70.125 0.275,0 21.8625,-70.125 17.05,0 21.45,70.125 0.275,0 19.1125,-70.125 17.6,0 -28.3250004,97.35 -16.4999996,0 -22.55,-74.1125 -0.275,0 -22.55,74.1125 -15.95,0 -28.737497,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5662"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 24.435016,431.35594 q 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.412504,-0.1375 20.900004,3.4375 9.4875,3.4375 16.3625,10.175 6.875,6.7375 10.725,16.225 3.85,9.4875 3.85,21.175 0,11.4125 -3.85,20.7625 -3.85,9.35 -10.725,16.0875 -6.875,6.7375 -16.3625,10.5875 -9.4875,3.7125 -20.900004,3.85 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 z m 18.15,-1.1 q 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 7.5625,0 13.750004,-2.75 6.1875,-2.75 10.5875,-7.5625 4.4,-4.8125 6.7375,-11.4125 2.475,-6.6 2.475,-14.4375 0,-7.2875 -2.475,-13.6125 -2.3375,-6.325 -6.7375,-11 -4.4,-4.8125 -10.5875,-7.425 -6.187504,-2.75 -13.750004,-2.75 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5664"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 137.68287,382.26844 33.825,0 q 7.0125,0 13.475,1.375 6.6,1.2375 11.6875,4.4 5.0875,3.1625 8.1125,8.525 3.025,5.3625 3.025,13.6125 0,10.5875 -5.9125,17.7375 -5.775,7.15 -16.6375,8.6625 l 25.85,43.0375 -20.9,0 -22.55,-41.25 -12.65,0 0,41.25 -17.325,0 0,-97.35 z m 30.8,41.25 q 3.7125,0 7.425,-0.275 3.7125,-0.4125 6.7375,-1.65 3.1625,-1.375 5.0875,-3.9875 1.925,-2.75 1.925,-7.5625 0,-4.2625 -1.7875,-6.875 -1.7875,-2.6125 -4.675,-3.85 -2.8875,-1.375 -6.4625,-1.7875 -3.4375,-0.4125 -6.7375,-0.4125 l -14.9875,0 0,26.4 13.475,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5666"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 221.50746,382.26844 17.325,0 0,41.25 0.825,0 40.2875,-41.25 23.375,0 -45.5125,44.9625 48.5375,52.3875 -24.3375,0 -42.2125,-47.85 -0.9625,0 0,47.85 -17.325,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5668"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 14 KiB |
157
YggdrasilSwiftUI/Assets.xcassets/YggdrasilLogo.imageset/ygg-neilalexander 2.svg
vendored
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
sodipodi:docname="drawing.svg"
|
||||||
|
inkscape:version="0.91 r13725"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4240"
|
||||||
|
viewBox="0 0 981.96461 321.60015"
|
||||||
|
height="90.762711mm"
|
||||||
|
width="277.13223mm">
|
||||||
|
<defs
|
||||||
|
id="defs4242" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-top="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="1"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="1021"
|
||||||
|
inkscape:window-width="2048"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:current-layer="layer2"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:cy="13.914395"
|
||||||
|
inkscape:cx="751.6295"
|
||||||
|
inkscape:zoom="0.66468037"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
id="base" />
|
||||||
|
<metadata
|
||||||
|
id="metadata4245">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(383.92494,-160.49328)" />
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer2"
|
||||||
|
inkscape:label="Layer 2"
|
||||||
|
transform="translate(383.92494,-160.49328)">
|
||||||
|
<path
|
||||||
|
style="fill:#000000"
|
||||||
|
d="m 352.74397,478.24119 c 0.92103,-3.76903 11.87131,-30.48993 21.5083,-52.48465 9.86344,-22.51152 9.67726,-21.6278 6.92943,-32.89221 -3.42997,-14.06075 -3.22164,-36.95243 0.44688,-49.10642 13.24423,-43.87864 47.63362,-73.61698 122.30718,-105.76556 24.32504,-10.47245 37.67777,-17.18807 47.80968,-24.04538 17.86083,-12.08828 36.4402,-33.06424 42.38057,-47.84736 1.25285,-3.11781 2.66096,-5.64051 3.12912,-5.60598 1.46014,0.10767 0.73701,44.30167 -0.9768,59.69719 -10.61597,95.36545 -42.95689,157.39345 -96.20598,184.51751 -30.73114,15.65385 -79.17559,21.45357 -101.74118,12.18037 -3.19081,-1.31125 -6.5492,-2.38408 -7.46311,-2.38408 -3.43636,0 -15.75824,32.89925 -19.29523,51.51802 -1.09802,5.78003 -2.76237,13.70787 -3.00898,14.91667 -5.50064,-0.0422 -0.35371,-0.0119 -8.18026,-0.0119 l -8.29605,0 z"
|
||||||
|
id="path4918"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ssssssscssssscscs" />
|
||||||
|
<g
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:150px;line-height:86.00000143%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
id="text4920"
|
||||||
|
transform="translate(-2,0)">
|
||||||
|
<path
|
||||||
|
d="m -345.34994,319.70594 -36.575,-55.6875 21.725,0 23.925,38.775 24.2,-38.775 20.625,0 -36.575,55.6875 0,41.6625 -17.325,0 0,-41.6625 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5638"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -202.55678,354.21844 q -18.0125,9.625 -40.2875,9.625 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.1375,0 20.9,2.75 9.7625,2.6125 17.4625,9.4875 l -12.7875,12.925 q -4.675,-4.5375 -11.4125,-7.0125 -6.6,-2.475 -14.025,-2.475 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 6.6,0 12.375,-1.2375 5.9125,-1.2375 10.45,-3.85 l 0,-22.9625 -19.9375,0 0,-15.675 37.2625,0 0,49.775 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5640"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -102.05346,354.21844 q -18.0125,9.625 -40.2875,9.625 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.1375,0 20.9,2.75 9.7625,2.6125 17.4625,9.4875 l -12.7875,12.925 q -4.675,-4.5375 -11.4125,-7.0125 -6.6,-2.475 -14.025,-2.475 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 6.6,0 12.375,-1.2375 5.9125,-1.2375 10.45,-3.85 l 0,-22.9625 -19.9375,0 0,-15.675 37.2625,0 0,49.775 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5642"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -90.037646,264.01844 38.3625,0 q 9.625,0 18.5625,3.025 8.9375,2.8875 15.8125,8.9375 6.875,6.05 11,15.2625 4.125,9.075 4.125,21.45 0,12.5125 -4.8125,21.725 -4.675,9.075 -12.2375,15.125 -7.425,5.9125 -16.6375,8.9375 -9.075,2.8875 -17.875,2.8875 l -36.3,0 0,-97.35 z m 30.25,81.675 q 8.1125,0 15.2625,-1.7875 7.2875,-1.925 12.65,-5.775 5.3625,-3.9875 8.3875,-10.175 3.1625,-6.325 3.1625,-15.2625 0,-8.8 -2.75,-15.125 -2.75,-6.325 -7.7,-10.175 -4.8125,-3.9875 -11.55,-5.775 -6.6,-1.925 -14.575,-1.925 l -15.8125,0 0,66 12.925,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5644"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 7.511578,264.01844 33.825,0 q 7.0125,0 13.475,1.375 6.6,1.2375 11.687502,4.4 5.0875,3.1625 8.1125,8.525 3.025,5.3625 3.025,13.6125 0,10.5875 -5.9125,17.7375 -5.775002,7.15 -16.637502,8.6625 l 25.850002,43.0375 -20.900002,0 -22.55,-41.25 -12.65,0 0,41.25 -17.325,0 0,-97.35 z m 30.8,41.25 q 3.7125,0 7.425,-0.275 3.7125,-0.4125 6.7375,-1.65 3.1625,-1.375 5.0875,-3.9875 1.925,-2.75 1.925,-7.5625 0,-4.2625 -1.7875,-6.875 -1.7875,-2.6125 -4.675,-3.85 -2.8875,-1.375 -6.4625,-1.7875 -3.4375,-0.4125 -6.7375,-0.4125 l -14.9875,0 0,26.4 13.475,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5646"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 126.82369,264.01844 14.9875,0 41.9375,97.35 -19.8,0 -9.075,-22.275 -42.2125,0 -8.8,22.275 -19.3875,0 42.35,-97.35 z m 22,60.225 -14.9875,-39.6 -15.2625,39.6 30.25,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5648"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 239.7639,284.91844 q -2.75,-3.9875 -7.425,-5.775 -4.5375,-1.925 -9.625,-1.925 -3.025,0 -5.9125,0.6875 -2.75,0.6875 -5.0875,2.2 -2.2,1.5125 -3.575,3.9875 -1.375,2.3375 -1.375,5.6375 0,4.95 3.4375,7.5625 3.4375,2.6125 8.525,4.5375 5.0875,1.925 11.1375,3.7125 6.05,1.7875 11.1375,4.95 5.0875,3.1625 8.525,8.3875 3.4375,5.225 3.4375,13.8875 0,7.8375 -2.8875,13.75 -2.8875,5.775 -7.8375,9.625 -4.8125,3.85 -11.275,5.775 -6.4625,1.925 -13.6125,1.925 -9.075,0 -17.4625,-3.025 -8.3875,-3.025 -14.4375,-10.175 l 13.0625,-12.65 q 3.1625,4.8125 8.25,7.5625 5.225,2.6125 11,2.6125 3.025,0 6.05,-0.825 3.025,-0.825 5.5,-2.475 2.475,-1.65 3.9875,-4.125 1.5125,-2.6125 1.5125,-5.9125 0,-5.3625 -3.4375,-8.25 -3.4375,-2.8875 -8.525,-4.8125 -5.0875,-2.0625 -11.1375,-3.85 -6.05,-1.7875 -11.1375,-4.8125 -5.0875,-3.1625 -8.525,-8.25 -3.4375,-5.225 -3.4375,-13.8875 0,-7.5625 3.025,-13.0625 3.1625,-5.5 8.1125,-9.075 5.0875,-3.7125 11.55,-5.5 6.4625,-1.7875 13.2,-1.7875 7.7,0 14.85,2.3375 7.2875,2.3375 13.0625,7.7 l -12.65,13.3375 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5650"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 264.21257,264.01844 17.325,0 0,97.35 -17.325,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5652"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 296.37837,264.01844 17.325,0 0,81.675 41.3875,0 0,15.675 -58.7125,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5654"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -369.13744,382.26844 22.9625,0 47.1625,72.325 0.275,0 0,-72.325 17.325,0 0,97.35 -22,0 -48.125,-74.6625 -0.275,0 0,74.6625 -17.325,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5656"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -270.48568,382.26844 64.4875,0 0,15.675 -47.1625,0 0,23.925 44.6875,0 0,15.675 -44.6875,0 0,26.4 49.6375,0 0,15.675 -66.9625,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5658"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -165.14057,397.94344 -29.8375,0 0,-15.675 77,0 0,15.675 -29.8375,0 0,81.675 -17.325,0 0,-81.675 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5660"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -111.36694,382.26844 18.974997,0 18.2875,70.125 0.275,0 21.8625,-70.125 17.05,0 21.45,70.125 0.275,0 19.1125,-70.125 17.6,0 -28.3250004,97.35 -16.4999996,0 -22.55,-74.1125 -0.275,0 -22.55,74.1125 -15.95,0 -28.737497,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5662"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 24.435016,431.35594 q 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.412504,-0.1375 20.900004,3.4375 9.4875,3.4375 16.3625,10.175 6.875,6.7375 10.725,16.225 3.85,9.4875 3.85,21.175 0,11.4125 -3.85,20.7625 -3.85,9.35 -10.725,16.0875 -6.875,6.7375 -16.3625,10.5875 -9.4875,3.7125 -20.900004,3.85 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 z m 18.15,-1.1 q 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 7.5625,0 13.750004,-2.75 6.1875,-2.75 10.5875,-7.5625 4.4,-4.8125 6.7375,-11.4125 2.475,-6.6 2.475,-14.4375 0,-7.2875 -2.475,-13.6125 -2.3375,-6.325 -6.7375,-11 -4.4,-4.8125 -10.5875,-7.425 -6.187504,-2.75 -13.750004,-2.75 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5664"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 137.68287,382.26844 33.825,0 q 7.0125,0 13.475,1.375 6.6,1.2375 11.6875,4.4 5.0875,3.1625 8.1125,8.525 3.025,5.3625 3.025,13.6125 0,10.5875 -5.9125,17.7375 -5.775,7.15 -16.6375,8.6625 l 25.85,43.0375 -20.9,0 -22.55,-41.25 -12.65,0 0,41.25 -17.325,0 0,-97.35 z m 30.8,41.25 q 3.7125,0 7.425,-0.275 3.7125,-0.4125 6.7375,-1.65 3.1625,-1.375 5.0875,-3.9875 1.925,-2.75 1.925,-7.5625 0,-4.2625 -1.7875,-6.875 -1.7875,-2.6125 -4.675,-3.85 -2.8875,-1.375 -6.4625,-1.7875 -3.4375,-0.4125 -6.7375,-0.4125 l -14.9875,0 0,26.4 13.475,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5666"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 221.50746,382.26844 17.325,0 0,41.25 0.825,0 40.2875,-41.25 23.375,0 -45.5125,44.9625 48.5375,52.3875 -24.3375,0 -42.2125,-47.85 -0.9625,0 0,47.85 -17.325,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5668"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 14 KiB |
157
YggdrasilSwiftUI/Assets.xcassets/YggdrasilLogo.imageset/ygg-neilalexander.svg
vendored
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
sodipodi:docname="drawing.svg"
|
||||||
|
inkscape:version="0.91 r13725"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4240"
|
||||||
|
viewBox="0 0 981.96461 321.60015"
|
||||||
|
height="90.762711mm"
|
||||||
|
width="277.13223mm">
|
||||||
|
<defs
|
||||||
|
id="defs4242" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-top="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="1"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="1021"
|
||||||
|
inkscape:window-width="2048"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:current-layer="layer2"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:cy="13.914395"
|
||||||
|
inkscape:cx="751.6295"
|
||||||
|
inkscape:zoom="0.66468037"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
id="base" />
|
||||||
|
<metadata
|
||||||
|
id="metadata4245">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(383.92494,-160.49328)" />
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer2"
|
||||||
|
inkscape:label="Layer 2"
|
||||||
|
transform="translate(383.92494,-160.49328)">
|
||||||
|
<path
|
||||||
|
style="fill:#000000"
|
||||||
|
d="m 352.74397,478.24119 c 0.92103,-3.76903 11.87131,-30.48993 21.5083,-52.48465 9.86344,-22.51152 9.67726,-21.6278 6.92943,-32.89221 -3.42997,-14.06075 -3.22164,-36.95243 0.44688,-49.10642 13.24423,-43.87864 47.63362,-73.61698 122.30718,-105.76556 24.32504,-10.47245 37.67777,-17.18807 47.80968,-24.04538 17.86083,-12.08828 36.4402,-33.06424 42.38057,-47.84736 1.25285,-3.11781 2.66096,-5.64051 3.12912,-5.60598 1.46014,0.10767 0.73701,44.30167 -0.9768,59.69719 -10.61597,95.36545 -42.95689,157.39345 -96.20598,184.51751 -30.73114,15.65385 -79.17559,21.45357 -101.74118,12.18037 -3.19081,-1.31125 -6.5492,-2.38408 -7.46311,-2.38408 -3.43636,0 -15.75824,32.89925 -19.29523,51.51802 -1.09802,5.78003 -2.76237,13.70787 -3.00898,14.91667 -5.50064,-0.0422 -0.35371,-0.0119 -8.18026,-0.0119 l -8.29605,0 z"
|
||||||
|
id="path4918"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ssssssscssssscscs" />
|
||||||
|
<g
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:150px;line-height:86.00000143%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
id="text4920"
|
||||||
|
transform="translate(-2,0)">
|
||||||
|
<path
|
||||||
|
d="m -345.34994,319.70594 -36.575,-55.6875 21.725,0 23.925,38.775 24.2,-38.775 20.625,0 -36.575,55.6875 0,41.6625 -17.325,0 0,-41.6625 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5638"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -202.55678,354.21844 q -18.0125,9.625 -40.2875,9.625 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.1375,0 20.9,2.75 9.7625,2.6125 17.4625,9.4875 l -12.7875,12.925 q -4.675,-4.5375 -11.4125,-7.0125 -6.6,-2.475 -14.025,-2.475 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 6.6,0 12.375,-1.2375 5.9125,-1.2375 10.45,-3.85 l 0,-22.9625 -19.9375,0 0,-15.675 37.2625,0 0,49.775 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5640"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -102.05346,354.21844 q -18.0125,9.625 -40.2875,9.625 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.1375,0 20.9,2.75 9.7625,2.6125 17.4625,9.4875 l -12.7875,12.925 q -4.675,-4.5375 -11.4125,-7.0125 -6.6,-2.475 -14.025,-2.475 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 6.6,0 12.375,-1.2375 5.9125,-1.2375 10.45,-3.85 l 0,-22.9625 -19.9375,0 0,-15.675 37.2625,0 0,49.775 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5642"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -90.037646,264.01844 38.3625,0 q 9.625,0 18.5625,3.025 8.9375,2.8875 15.8125,8.9375 6.875,6.05 11,15.2625 4.125,9.075 4.125,21.45 0,12.5125 -4.8125,21.725 -4.675,9.075 -12.2375,15.125 -7.425,5.9125 -16.6375,8.9375 -9.075,2.8875 -17.875,2.8875 l -36.3,0 0,-97.35 z m 30.25,81.675 q 8.1125,0 15.2625,-1.7875 7.2875,-1.925 12.65,-5.775 5.3625,-3.9875 8.3875,-10.175 3.1625,-6.325 3.1625,-15.2625 0,-8.8 -2.75,-15.125 -2.75,-6.325 -7.7,-10.175 -4.8125,-3.9875 -11.55,-5.775 -6.6,-1.925 -14.575,-1.925 l -15.8125,0 0,66 12.925,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5644"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 7.511578,264.01844 33.825,0 q 7.0125,0 13.475,1.375 6.6,1.2375 11.687502,4.4 5.0875,3.1625 8.1125,8.525 3.025,5.3625 3.025,13.6125 0,10.5875 -5.9125,17.7375 -5.775002,7.15 -16.637502,8.6625 l 25.850002,43.0375 -20.900002,0 -22.55,-41.25 -12.65,0 0,41.25 -17.325,0 0,-97.35 z m 30.8,41.25 q 3.7125,0 7.425,-0.275 3.7125,-0.4125 6.7375,-1.65 3.1625,-1.375 5.0875,-3.9875 1.925,-2.75 1.925,-7.5625 0,-4.2625 -1.7875,-6.875 -1.7875,-2.6125 -4.675,-3.85 -2.8875,-1.375 -6.4625,-1.7875 -3.4375,-0.4125 -6.7375,-0.4125 l -14.9875,0 0,26.4 13.475,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5646"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 126.82369,264.01844 14.9875,0 41.9375,97.35 -19.8,0 -9.075,-22.275 -42.2125,0 -8.8,22.275 -19.3875,0 42.35,-97.35 z m 22,60.225 -14.9875,-39.6 -15.2625,39.6 30.25,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5648"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 239.7639,284.91844 q -2.75,-3.9875 -7.425,-5.775 -4.5375,-1.925 -9.625,-1.925 -3.025,0 -5.9125,0.6875 -2.75,0.6875 -5.0875,2.2 -2.2,1.5125 -3.575,3.9875 -1.375,2.3375 -1.375,5.6375 0,4.95 3.4375,7.5625 3.4375,2.6125 8.525,4.5375 5.0875,1.925 11.1375,3.7125 6.05,1.7875 11.1375,4.95 5.0875,3.1625 8.525,8.3875 3.4375,5.225 3.4375,13.8875 0,7.8375 -2.8875,13.75 -2.8875,5.775 -7.8375,9.625 -4.8125,3.85 -11.275,5.775 -6.4625,1.925 -13.6125,1.925 -9.075,0 -17.4625,-3.025 -8.3875,-3.025 -14.4375,-10.175 l 13.0625,-12.65 q 3.1625,4.8125 8.25,7.5625 5.225,2.6125 11,2.6125 3.025,0 6.05,-0.825 3.025,-0.825 5.5,-2.475 2.475,-1.65 3.9875,-4.125 1.5125,-2.6125 1.5125,-5.9125 0,-5.3625 -3.4375,-8.25 -3.4375,-2.8875 -8.525,-4.8125 -5.0875,-2.0625 -11.1375,-3.85 -6.05,-1.7875 -11.1375,-4.8125 -5.0875,-3.1625 -8.525,-8.25 -3.4375,-5.225 -3.4375,-13.8875 0,-7.5625 3.025,-13.0625 3.1625,-5.5 8.1125,-9.075 5.0875,-3.7125 11.55,-5.5 6.4625,-1.7875 13.2,-1.7875 7.7,0 14.85,2.3375 7.2875,2.3375 13.0625,7.7 l -12.65,13.3375 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5650"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 264.21257,264.01844 17.325,0 0,97.35 -17.325,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5652"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 296.37837,264.01844 17.325,0 0,81.675 41.3875,0 0,15.675 -58.7125,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5654"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -369.13744,382.26844 22.9625,0 47.1625,72.325 0.275,0 0,-72.325 17.325,0 0,97.35 -22,0 -48.125,-74.6625 -0.275,0 0,74.6625 -17.325,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5656"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -270.48568,382.26844 64.4875,0 0,15.675 -47.1625,0 0,23.925 44.6875,0 0,15.675 -44.6875,0 0,26.4 49.6375,0 0,15.675 -66.9625,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5658"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -165.14057,397.94344 -29.8375,0 0,-15.675 77,0 0,15.675 -29.8375,0 0,81.675 -17.325,0 0,-81.675 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5660"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m -111.36694,382.26844 18.974997,0 18.2875,70.125 0.275,0 21.8625,-70.125 17.05,0 21.45,70.125 0.275,0 19.1125,-70.125 17.6,0 -28.3250004,97.35 -16.4999996,0 -22.55,-74.1125 -0.275,0 -22.55,74.1125 -15.95,0 -28.737497,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5662"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 24.435016,431.35594 q 0,-11.6875 3.85,-21.175 3.85,-9.625 10.5875,-16.3625 6.875,-6.7375 16.225,-10.3125 9.4875,-3.7125 20.7625,-3.7125 11.412504,-0.1375 20.900004,3.4375 9.4875,3.4375 16.3625,10.175 6.875,6.7375 10.725,16.225 3.85,9.4875 3.85,21.175 0,11.4125 -3.85,20.7625 -3.85,9.35 -10.725,16.0875 -6.875,6.7375 -16.3625,10.5875 -9.4875,3.7125 -20.900004,3.85 -11.275,0 -20.7625,-3.575 -9.35,-3.7125 -16.225,-10.3125 -6.7375,-6.7375 -10.5875,-16.0875 -3.85,-9.35 -3.85,-20.7625 z m 18.15,-1.1 q 0,7.8375 2.3375,14.4375 2.475,6.6 6.875,11.4125 4.4,4.8125 10.45,7.5625 6.1875,2.75 13.75,2.75 7.5625,0 13.750004,-2.75 6.1875,-2.75 10.5875,-7.5625 4.4,-4.8125 6.7375,-11.4125 2.475,-6.6 2.475,-14.4375 0,-7.2875 -2.475,-13.6125 -2.3375,-6.325 -6.7375,-11 -4.4,-4.8125 -10.5875,-7.425 -6.187504,-2.75 -13.750004,-2.75 -7.5625,0 -13.75,2.75 -6.05,2.6125 -10.45,7.425 -4.4,4.675 -6.875,11 -2.3375,6.325 -2.3375,13.6125 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5664"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 137.68287,382.26844 33.825,0 q 7.0125,0 13.475,1.375 6.6,1.2375 11.6875,4.4 5.0875,3.1625 8.1125,8.525 3.025,5.3625 3.025,13.6125 0,10.5875 -5.9125,17.7375 -5.775,7.15 -16.6375,8.6625 l 25.85,43.0375 -20.9,0 -22.55,-41.25 -12.65,0 0,41.25 -17.325,0 0,-97.35 z m 30.8,41.25 q 3.7125,0 7.425,-0.275 3.7125,-0.4125 6.7375,-1.65 3.1625,-1.375 5.0875,-3.9875 1.925,-2.75 1.925,-7.5625 0,-4.2625 -1.7875,-6.875 -1.7875,-2.6125 -4.675,-3.85 -2.8875,-1.375 -6.4625,-1.7875 -3.4375,-0.4125 -6.7375,-0.4125 l -14.9875,0 0,26.4 13.475,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5666"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 221.50746,382.26844 17.325,0 0,41.25 0.825,0 40.2875,-41.25 23.375,0 -45.5125,44.9625 48.5375,52.3875 -24.3375,0 -42.2125,-47.85 -0.9625,0 0,47.85 -17.325,0 0,-97.35 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:137.5px;line-height:86.00000143%;font-family:Avenir;-inkscape-font-specification:'Avenir Heavy';letter-spacing:1.35000002px"
|
||||||
|
id="path5668"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 14 KiB |
|
@ -8,18 +8,32 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct PeersView: View {
|
struct PeersView: View {
|
||||||
@State private var peers = ["Paul", "Taylor", "Adele"]
|
// @Binding public var yggdrasilConfiguration: ConfigurationProxy
|
||||||
|
@ObservedObject private var appDelegate = Application.appDelegate
|
||||||
|
|
||||||
@State private var multicastAdvertise = false
|
@State private var peers = ["Paul", "Taylor", "Adele"]
|
||||||
@State private var multicastListen = false
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
Section(content: {
|
Section(content: {
|
||||||
ForEach(peers, id: \.self) { peer in
|
ForEach(Array(appDelegate.yggdrasilConfig.peers.enumerated()), id: \.offset) { index, peer in
|
||||||
|
HStack() {
|
||||||
Text(peer)
|
Text(peer)
|
||||||
|
//TextField("", text: $yggdrasilConfiguration.peers[index])
|
||||||
|
// .multilineTextAlignment(.leading)
|
||||||
|
#if os(macOS)
|
||||||
|
Spacer()
|
||||||
|
Button(role: .destructive) {
|
||||||
|
print("Deleting")
|
||||||
|
} label: {
|
||||||
|
Image(systemName: "xmark.circle.fill")
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.onDelete(perform: delete)
|
.onDelete(perform: delete)
|
||||||
|
|
||||||
Text("Yggdrasil will automatically attempt to connect to configured peers when started. If you configure more than one peer, your device may carry traffic on behalf of other network nodes. Avoid this by configuring only a single peer. Data charges may apply when using mobile data.")
|
Text("Yggdrasil will automatically attempt to connect to configured peers when started. If you configure more than one peer, your device may carry traffic on behalf of other network nodes. Avoid this by configuring only a single peer. Data charges may apply when using mobile data.")
|
||||||
.font(.system(size: 11))
|
.font(.system(size: 11))
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
|
@ -28,7 +42,7 @@ struct PeersView: View {
|
||||||
})
|
})
|
||||||
|
|
||||||
Section(content: {
|
Section(content: {
|
||||||
Toggle(isOn: $multicastAdvertise) {
|
Toggle(isOn: $appDelegate.yggdrasilConfig.multicastBeacons) {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
Text("Discoverable over multicast")
|
Text("Discoverable over multicast")
|
||||||
Text("Make your device discoverable to other Yggdrasil nodes on the same Wi-Fi network.")
|
Text("Make your device discoverable to other Yggdrasil nodes on the same Wi-Fi network.")
|
||||||
|
@ -36,7 +50,7 @@ struct PeersView: View {
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Toggle(isOn: $multicastListen) {
|
Toggle(isOn: $appDelegate.yggdrasilConfig.multicastListen) {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
Text("Search for multicast peers")
|
Text("Search for multicast peers")
|
||||||
Text("Automatically connect to discoverable Yggdrasil nodes on the same Wi-Fi network.")
|
Text("Automatically connect to discoverable Yggdrasil nodes on the same Wi-Fi network.")
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct SettingsView: View {
|
struct SettingsView: View {
|
||||||
@State private var deviceName = ""
|
//@Binding public var yggdrasilConfiguration: ConfigurationProxy
|
||||||
|
@ObservedObject private var appDelegate = Application.appDelegate
|
||||||
|
|
||||||
@State private var autoStartOnWiFi = false
|
@State private var deviceName = ""
|
||||||
@State private var autoStartOnCellular = false
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
|
@ -22,8 +22,14 @@ struct SettingsView: View {
|
||||||
})
|
})
|
||||||
|
|
||||||
Section(content: {
|
Section(content: {
|
||||||
Toggle("Wi-Fi", isOn: $autoStartOnWiFi)
|
Toggle("Any network connection", isOn: $appDelegate.yggdrasilConfig.autoStartAny)
|
||||||
Toggle("Mobile Network", isOn: $autoStartOnCellular)
|
Toggle("Wi-Fi networks", isOn: $appDelegate.yggdrasilConfig.autoStartWiFi)
|
||||||
|
#if os(macOS)
|
||||||
|
Toggle("Ethernet networks", isOn: $appDelegate.yggdrasilConfig.autoStartEthernet)
|
||||||
|
#endif
|
||||||
|
#if os(iOS)
|
||||||
|
Toggle("Mobile data", isOn: $appDelegate.yggdrasilConfig.autoStartMobile)
|
||||||
|
#endif
|
||||||
}, header: {
|
}, header: {
|
||||||
Text("Automatically start when connected to")
|
Text("Automatically start when connected to")
|
||||||
})
|
})
|
||||||
|
@ -36,6 +42,7 @@ struct SettingsView: View {
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
.buttonStyle(.link)
|
.buttonStyle(.link)
|
||||||
#endif
|
#endif
|
||||||
|
.foregroundColor(.accentColor)
|
||||||
Text("Import configuration from another device, including the public key and Yggdrasil IP address.")
|
Text("Import configuration from another device, including the public key and Yggdrasil IP address.")
|
||||||
.font(.system(size: 11))
|
.font(.system(size: 11))
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
|
@ -48,6 +55,7 @@ struct SettingsView: View {
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
.buttonStyle(.link)
|
.buttonStyle(.link)
|
||||||
#endif
|
#endif
|
||||||
|
.foregroundColor(.accentColor)
|
||||||
Text("Configuration will be exported as a file. Your configuration contains your private key which is extremely sensitive. Do not share it with anyone.")
|
Text("Configuration will be exported as a file. Your configuration contains your private key which is extremely sensitive. Do not share it with anyone.")
|
||||||
.font(.system(size: 11))
|
.font(.system(size: 11))
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
|
|
|
@ -14,8 +14,6 @@ typealias MyListStyle = SidebarListStyle
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct StatusView: View {
|
struct StatusView: View {
|
||||||
@Binding public var yggdrasilConfiguration: ConfigurationProxy
|
|
||||||
|
|
||||||
@ObservedObject private var appDelegate = Application.appDelegate
|
@ObservedObject private var appDelegate = Application.appDelegate
|
||||||
|
|
||||||
@State private var statusBadgeColor: SwiftUI.Color = .gray
|
@State private var statusBadgeColor: SwiftUI.Color = .gray
|
||||||
|
@ -35,9 +33,9 @@ struct StatusView: View {
|
||||||
if !appDelegate.yggdrasilEnabled {
|
if !appDelegate.yggdrasilEnabled {
|
||||||
return "Not enabled"
|
return "Not enabled"
|
||||||
} else if !appDelegate.yggdrasilConnected {
|
} else if !appDelegate.yggdrasilConnected {
|
||||||
return "Not connected"
|
return "No peers connected"
|
||||||
} else {
|
} else {
|
||||||
return "Connected"
|
return "Connected to \(appDelegate.yggdrasilPeers.count) peer(s)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,9 +44,6 @@ struct StatusView: View {
|
||||||
Section(content: {
|
Section(content: {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
Toggle("Enable Yggdrasil", isOn: $appDelegate.yggdrasilEnabled)
|
Toggle("Enable Yggdrasil", isOn: $appDelegate.yggdrasilEnabled)
|
||||||
.onTapGesture {
|
|
||||||
appDelegate.toggleYggdrasil()
|
|
||||||
}
|
|
||||||
HStack {
|
HStack {
|
||||||
Image(systemName: "circlebadge.fill")
|
Image(systemName: "circlebadge.fill")
|
||||||
.foregroundColor(statusBadgeColor)
|
.foregroundColor(statusBadgeColor)
|
||||||
|
@ -58,6 +53,12 @@ struct StatusView: View {
|
||||||
.onChange(of: appDelegate.yggdrasilEnabled) { newValue in
|
.onChange(of: appDelegate.yggdrasilEnabled) { newValue in
|
||||||
statusBadgeColor = getStatusBadgeColor()
|
statusBadgeColor = getStatusBadgeColor()
|
||||||
}
|
}
|
||||||
|
.onChange(of: appDelegate.yggdrasilConnected) { newValue in
|
||||||
|
statusBadgeColor = getStatusBadgeColor()
|
||||||
|
}
|
||||||
|
.onChange(of: appDelegate.yggdrasilPeers.count) { newValue in
|
||||||
|
statusBadgeColor = getStatusBadgeColor()
|
||||||
|
}
|
||||||
Text(statusBadgeText)
|
Text(statusBadgeText)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
.font(.system(size: 11))
|
.font(.system(size: 11))
|
||||||
|
@ -67,6 +68,12 @@ struct StatusView: View {
|
||||||
.onChange(of: appDelegate.yggdrasilEnabled) { newValue in
|
.onChange(of: appDelegate.yggdrasilEnabled) { newValue in
|
||||||
statusBadgeText = getStatusBadgeText()
|
statusBadgeText = getStatusBadgeText()
|
||||||
}
|
}
|
||||||
|
.onChange(of: appDelegate.yggdrasilConnected) { newValue in
|
||||||
|
statusBadgeText = getStatusBadgeText()
|
||||||
|
}
|
||||||
|
.onChange(of: appDelegate.yggdrasilPeers.count) { newValue in
|
||||||
|
statusBadgeText = getStatusBadgeText()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HStack {
|
HStack {
|
||||||
|
@ -83,29 +90,38 @@ struct StatusView: View {
|
||||||
Spacer()
|
Spacer()
|
||||||
Text(appDelegate.yggdrasilIP)
|
Text(appDelegate.yggdrasilIP)
|
||||||
.foregroundColor(Color.gray)
|
.foregroundColor(Color.gray)
|
||||||
|
.truncationMode(.head)
|
||||||
|
.lineLimit(1)
|
||||||
|
.textSelection(.enabled)
|
||||||
}
|
}
|
||||||
HStack {
|
HStack {
|
||||||
Text("Subnet")
|
Text("Subnet")
|
||||||
Spacer()
|
Spacer()
|
||||||
Text(appDelegate.yggdrasilSubnet)
|
Text(appDelegate.yggdrasilSubnet)
|
||||||
.foregroundColor(Color.gray)
|
.foregroundColor(Color.gray)
|
||||||
|
.truncationMode(.head)
|
||||||
|
.lineLimit(1)
|
||||||
|
.textSelection(.enabled)
|
||||||
}
|
}
|
||||||
HStack {
|
HStack {
|
||||||
Text("Coordinates")
|
Text("Coordinates")
|
||||||
Spacer()
|
Spacer()
|
||||||
Text(appDelegate.yggdrasilCoords)
|
Text(appDelegate.yggdrasilCoords)
|
||||||
.foregroundColor(Color.gray)
|
.foregroundColor(Color.gray)
|
||||||
|
.truncationMode(.tail)
|
||||||
|
.lineLimit(1)
|
||||||
|
.textSelection(.enabled)
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
HStack {
|
HStack {
|
||||||
Text("Public Key")
|
Text("Public Key")
|
||||||
Spacer()
|
Spacer()
|
||||||
Text("N/A")
|
Text(appDelegate.yggdrasilPublicKey)
|
||||||
.foregroundColor(Color.gray)
|
.foregroundColor(Color.gray)
|
||||||
.font(.system(size: 15, design: .monospaced))
|
.font(.system(size: 13, design: .monospaced))
|
||||||
.truncationMode(.tail)
|
.truncationMode(.tail)
|
||||||
|
.lineLimit(1)
|
||||||
|
.textSelection(.enabled)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
.formStyle(.grouped)
|
.formStyle(.grouped)
|
||||||
|
@ -118,8 +134,6 @@ struct StatusView: View {
|
||||||
|
|
||||||
struct StatusView_Previews: PreviewProvider {
|
struct StatusView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
@State var config = ConfigurationProxy()
|
StatusView()
|
||||||
|
|
||||||
StatusView(yggdrasilConfiguration: $config)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|