├── eca.gif
├── README.md
├── ECAExplorer
├── ECAExplorer.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── project.pbxproj
├── ECAExplorer.entitlements
└── ECA
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ ├── ECAModel.swift
│ ├── RuleView.swift
│ ├── ECAView.swift
│ ├── AppDelegate.swift
│ └── Base.lproj
│ └── MainMenu.xib
├── LICENSE
└── .gitignore
/eca.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nst/ECAExplorer/master/eca.gif
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ECAExplorer
2 | A simple and interactive tool to explore Elementary Cellular Automata, in Swift
3 |
4 | Download: [ecaexplorer\_0\_2.zip](http://www.seriot.ch/ecaexplorer/ecaexplorer_0_2.zip) (2.3 MB)
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ECAExplorer/ECAExplorer.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ECAExplorer/ECAExplorer.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-write
8 |
9 | com.apple.security.network.client
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Nicolas Seriot
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ECAExplorer/ECA/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/ECAExplorer/ECA/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 0.2
21 | CFBundleVersion
22 | 1
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSAppTransportSecurity
26 |
27 | NSExceptionDomains
28 |
29 | seriot.ch
30 |
31 | NSIncludesSubdomains
32 |
33 | NSTemporaryExceptionAllowsInsecureHTTPLoads
34 |
35 | NSTemporaryExceptionMinimumTLSVersion
36 | TLSv1.1
37 |
38 |
39 |
40 | NSHumanReadableCopyright
41 | Copyright © 2017 Nicolas Seriot. All rights reserved.
42 | NSMainNibFile
43 | MainMenu
44 | NSPrincipalClass
45 | NSApplication
46 |
47 |
48 |
--------------------------------------------------------------------------------
/ECAExplorer/ECA/ECAModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Model.swift
3 | // ECA
4 | //
5 | // Created by nst on 03.06.17.
6 | // Copyright © 2017 Nicolas Seriot. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | class ECAModel: NSObject {
12 |
13 | var firstRow: [Int] = []
14 | var ruleBits: [Int] = [0,0,0,0,0,0,0,0]
15 | var rule: UInt8 = 0 {
16 | didSet {
17 | let ruleBin = String(rule, radix: 2)
18 | let ruleBinPad = String(repeating: "0", count: (8 - ruleBin.characters.count)) + ruleBin
19 | ruleBits = []
20 |
21 | assert(ruleBinPad.characters.count == 8)
22 |
23 | for c in ruleBinPad.characters {
24 | switch c {
25 | case "0":
26 | ruleBits.append(0)
27 | case "1":
28 | ruleBits.append(1)
29 | default:
30 | assertionFailure()
31 | }
32 | }
33 |
34 | ruleBits.reverse()
35 | }
36 | }
37 |
38 | init(width: Int) {
39 | self.firstRow = Array(repeating: 0, count: width)
40 | }
41 |
42 | func next(row: [Int]) -> [Int] {
43 |
44 | let r = [row[row.count-1]] + row + [row[0]]
45 |
46 | var n: [Int] = []
47 |
48 | for i in 0.. CGRect {
63 | return CGRect(x: col * CELL_SIZE,
64 | y: row * CELL_SIZE,
65 | width: CELL_SIZE,
66 | height: CELL_SIZE)
67 | }
68 |
69 | func drawRow(row: [Int], rowIndex: Int, context c: CGContext) {
70 |
71 | for (i,cell) in row.enumerated() {
72 | let rect = self.rectForCell(col: i, row: rowIndex)
73 |
74 | var fillColor = NSColor.white
75 | if cell == 1 {
76 | fillColor = NSColor.black
77 | }
78 |
79 | c.setFillColor(fillColor.cgColor)
80 | c.fill(rect)
81 |
82 | c.setStrokeColor(NSColor.lightGray.cgColor)
83 | c.stroke(rect)
84 | }
85 | }
86 |
87 | override func mouseDown(with event: NSEvent) {
88 |
89 | let clickPoint = convert(event.locationInWindow, from: self.superview)
90 |
91 | //if clickPoint.y > CGFloat(CELL_SIZE) { return }
92 |
93 | let col = Int(clickPoint.x / CGFloat(CELL_SIZE))
94 |
95 | colFlipInitialState = delegate?.ecaModel.firstRow[col]
96 | delegate?.ecaModel.flipColumn(column: col)
97 |
98 | self.needsDisplay = true
99 | }
100 |
101 | override func mouseDragged(with event: NSEvent) {
102 | let clickPoint = convert(event.locationInWindow, from: self.superview)
103 | let col = Int(clickPoint.x / CGFloat(CELL_SIZE))
104 |
105 | guard let row = delegate?.ecaModel.firstRow else { return }
106 | guard col >= 0 else { return }
107 | guard col < row.count else { return }
108 |
109 | if row[col] != colFlipInitialState { return }
110 |
111 | colFlipInitialState = row[col]
112 | delegate?.ecaModel.flipColumn(column: col)
113 |
114 | self.needsDisplay = true
115 | }
116 | }
117 |
118 | extension NSView {
119 | func PNGRepresentation() -> Data? {
120 | guard let rep = self.bitmapImageRepForCachingDisplay(in: self.bounds) else { return nil }
121 | self.cacheDisplay(in: self.bounds, to: rep)
122 | return rep.representation(using: .PNG, properties: [:])
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/ECAExplorer/ECA/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ECA
4 | //
5 | // Created by nst on 03.06.17.
6 | // Copyright © 2017 Nicolas Seriot. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | @NSApplicationMain
12 | class AppDelegate: NSObject, NSApplicationDelegate, RuleViewDelegate, ECAViewDelegate, NSTextFieldDelegate {
13 |
14 | var ecaModel: ECAModel = ECAModel(width: 73)
15 |
16 | @IBOutlet weak var window: NSWindow!
17 | @IBOutlet weak var ruleView: RuleView!
18 | @IBOutlet weak var ecaView: ECAView!
19 | @IBOutlet weak var ruleTextField: NSTextField!
20 |
21 | var rule: UInt8 {
22 | get { return ecaModel.rule }
23 | set {
24 | ruleTextField.stringValue = "\(newValue)"
25 | ecaModel.rule = newValue
26 | ecaView.needsDisplay = true
27 | }
28 | }
29 |
30 | func applicationDidFinishLaunching(_ aNotification: Notification) {
31 | // Insert code here to initialize your application
32 | checkForUpdates()
33 | }
34 |
35 | func applicationWillTerminate(_ aNotification: Notification) {
36 | // Insert code here to tear down your application
37 | }
38 |
39 | override func awakeFromNib() {
40 | super.awakeFromNib()
41 |
42 | ecaModel.rule = 110
43 | ecaModel.firstRow[63] = 1
44 |
45 | ruleView.delegate = self
46 | ecaView.delegate = self
47 |
48 | ruleTextField.stringValue = "\(ecaModel.rule)"
49 | }
50 |
51 | @IBAction func textDidChange(sender: NSControl) {
52 |
53 | let newRuleString = ruleTextField.stringValue
54 |
55 | if let newRuleInt = UInt8(newRuleString) {
56 | ecaModel.rule = newRuleInt
57 | ruleView.needsDisplay = true
58 | ecaView.needsDisplay = true
59 | } else {
60 | print("ruleView:", ruleView)
61 | ruleTextField.stringValue = "\(ecaModel.rule)"
62 | }
63 | }
64 |
65 | @IBAction func saveImageAction(sender: NSMenuItem?) {
66 |
67 | guard let window = self.window else { return }
68 |
69 | guard let pngData = ecaView.PNGRepresentation() else { return }
70 |
71 | let savePanel = NSSavePanel()
72 | let timestamp = Date().timeIntervalSince1970
73 | savePanel.nameFieldStringValue = "rule_\(ecaModel.rule)_\(timestamp).png"
74 |
75 | savePanel.beginSheetModal(for: window) { (result: Int) -> Void in
76 | if result == NSFileHandlingPanelOKButton {
77 | guard let exportedFileURL = savePanel.url else { return }
78 | do {
79 | try pngData.write(to: exportedFileURL)
80 | } catch let e {
81 | Swift.print(e)
82 | }
83 | }
84 | }
85 | }
86 |
87 | func checkForUpdates() {
88 |
89 | let url = URL(string:"http://www.seriot.ch/ecaexplorer/ecaexplorer.json")
90 |
91 | URLSession.shared.dataTask(with: url!) { (optionalData, response, error) in
92 |
93 | DispatchQueue.main.async {
94 |
95 | guard let data = optionalData,
96 | let optionalDict = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String:AnyObject],
97 | let d = optionalDict,
98 | let latestVersionString = d["latest_version_string"] as? String,
99 | let latestVersionURL = d["latest_version_url"] as? String
100 | else {
101 | return
102 | }
103 |
104 | print("-- latestVersionString: \(latestVersionString)")
105 | print("-- latestVersionURL: \(latestVersionURL)")
106 |
107 | guard let currentVersionString = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String else { return }
108 |
109 | let needsUpdate = currentVersionString < latestVersionString
110 |
111 | print("-- needsUpdate: \(needsUpdate)")
112 | if needsUpdate == false { return }
113 |
114 | let a = NSAlert()
115 | a.messageText = "ECAExplorer \(latestVersionString) is Available"
116 | a.informativeText = "Please download it and replace the current version.";
117 | a.addButton(withTitle: "Download")
118 | a.addButton(withTitle: "Cancel")
119 | a.alertStyle = .critical
120 |
121 | let modalResponse = a.runModal()
122 |
123 | if modalResponse == NSAlertFirstButtonReturn {
124 | if let downloadURL = URL(string:latestVersionURL) {
125 | NSWorkspace.shared().open(downloadURL)
126 | }
127 | }
128 | }
129 | }.resume()
130 | }
131 |
132 | // MARK: NSApplicationDelegate
133 |
134 | func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
135 | return true
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/ECAExplorer/ECAExplorer.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 038C31741EE34A460071546D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 038C31731EE34A460071546D /* AppDelegate.swift */; };
11 | 038C31761EE34A460071546D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 038C31751EE34A460071546D /* Assets.xcassets */; };
12 | 038C31791EE34A460071546D /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 038C31771EE34A460071546D /* MainMenu.xib */; };
13 | 038C31831EE34B5F0071546D /* ECAView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 038C31821EE34B5F0071546D /* ECAView.swift */; };
14 | 038C31851EE34B6F0071546D /* RuleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 038C31841EE34B6F0071546D /* RuleView.swift */; };
15 | 038C31871EE35FE90071546D /* ECAModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 038C31861EE35FE90071546D /* ECAModel.swift */; };
16 | /* End PBXBuildFile section */
17 |
18 | /* Begin PBXFileReference section */
19 | 038C31701EE34A460071546D /* ECAExplorer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ECAExplorer.app; sourceTree = BUILT_PRODUCTS_DIR; };
20 | 038C31731EE34A460071546D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
21 | 038C31751EE34A460071546D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
22 | 038C31781EE34A460071546D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
23 | 038C317A1EE34A460071546D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
24 | 038C31821EE34B5F0071546D /* ECAView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ECAView.swift; sourceTree = ""; };
25 | 038C31841EE34B6F0071546D /* RuleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuleView.swift; sourceTree = ""; };
26 | 038C31861EE35FE90071546D /* ECAModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ECAModel.swift; sourceTree = ""; };
27 | 038C31881EE464F10071546D /* ECAExplorer.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ECAExplorer.entitlements; sourceTree = ""; };
28 | /* End PBXFileReference section */
29 |
30 | /* Begin PBXFrameworksBuildPhase section */
31 | 038C316D1EE34A460071546D /* Frameworks */ = {
32 | isa = PBXFrameworksBuildPhase;
33 | buildActionMask = 2147483647;
34 | files = (
35 | );
36 | runOnlyForDeploymentPostprocessing = 0;
37 | };
38 | /* End PBXFrameworksBuildPhase section */
39 |
40 | /* Begin PBXGroup section */
41 | 038C31671EE34A460071546D = {
42 | isa = PBXGroup;
43 | children = (
44 | 038C31881EE464F10071546D /* ECAExplorer.entitlements */,
45 | 038C31721EE34A460071546D /* ECA */,
46 | 038C31711EE34A460071546D /* Products */,
47 | );
48 | sourceTree = "";
49 | };
50 | 038C31711EE34A460071546D /* Products */ = {
51 | isa = PBXGroup;
52 | children = (
53 | 038C31701EE34A460071546D /* ECAExplorer.app */,
54 | );
55 | name = Products;
56 | sourceTree = "";
57 | };
58 | 038C31721EE34A460071546D /* ECA */ = {
59 | isa = PBXGroup;
60 | children = (
61 | 038C31841EE34B6F0071546D /* RuleView.swift */,
62 | 038C31821EE34B5F0071546D /* ECAView.swift */,
63 | 038C31731EE34A460071546D /* AppDelegate.swift */,
64 | 038C31861EE35FE90071546D /* ECAModel.swift */,
65 | 038C31751EE34A460071546D /* Assets.xcassets */,
66 | 038C31771EE34A460071546D /* MainMenu.xib */,
67 | 038C317A1EE34A460071546D /* Info.plist */,
68 | );
69 | path = ECA;
70 | sourceTree = "";
71 | };
72 | /* End PBXGroup section */
73 |
74 | /* Begin PBXNativeTarget section */
75 | 038C316F1EE34A460071546D /* ECAExplorer */ = {
76 | isa = PBXNativeTarget;
77 | buildConfigurationList = 038C317D1EE34A460071546D /* Build configuration list for PBXNativeTarget "ECAExplorer" */;
78 | buildPhases = (
79 | 038C316C1EE34A460071546D /* Sources */,
80 | 038C316D1EE34A460071546D /* Frameworks */,
81 | 038C316E1EE34A460071546D /* Resources */,
82 | );
83 | buildRules = (
84 | );
85 | dependencies = (
86 | );
87 | name = ECAExplorer;
88 | productName = ECA;
89 | productReference = 038C31701EE34A460071546D /* ECAExplorer.app */;
90 | productType = "com.apple.product-type.application";
91 | };
92 | /* End PBXNativeTarget section */
93 |
94 | /* Begin PBXProject section */
95 | 038C31681EE34A460071546D /* Project object */ = {
96 | isa = PBXProject;
97 | attributes = {
98 | LastSwiftUpdateCheck = 0820;
99 | LastUpgradeCheck = 0820;
100 | ORGANIZATIONNAME = "Nicolas Seriot";
101 | TargetAttributes = {
102 | 038C316F1EE34A460071546D = {
103 | CreatedOnToolsVersion = 8.2.1;
104 | DevelopmentTeam = VBYRKYS73S;
105 | ProvisioningStyle = Automatic;
106 | SystemCapabilities = {
107 | com.apple.Sandbox = {
108 | enabled = 1;
109 | };
110 | };
111 | };
112 | };
113 | };
114 | buildConfigurationList = 038C316B1EE34A460071546D /* Build configuration list for PBXProject "ECAExplorer" */;
115 | compatibilityVersion = "Xcode 3.2";
116 | developmentRegion = English;
117 | hasScannedForEncodings = 0;
118 | knownRegions = (
119 | en,
120 | Base,
121 | );
122 | mainGroup = 038C31671EE34A460071546D;
123 | productRefGroup = 038C31711EE34A460071546D /* Products */;
124 | projectDirPath = "";
125 | projectRoot = "";
126 | targets = (
127 | 038C316F1EE34A460071546D /* ECAExplorer */,
128 | );
129 | };
130 | /* End PBXProject section */
131 |
132 | /* Begin PBXResourcesBuildPhase section */
133 | 038C316E1EE34A460071546D /* Resources */ = {
134 | isa = PBXResourcesBuildPhase;
135 | buildActionMask = 2147483647;
136 | files = (
137 | 038C31761EE34A460071546D /* Assets.xcassets in Resources */,
138 | 038C31791EE34A460071546D /* MainMenu.xib in Resources */,
139 | );
140 | runOnlyForDeploymentPostprocessing = 0;
141 | };
142 | /* End PBXResourcesBuildPhase section */
143 |
144 | /* Begin PBXSourcesBuildPhase section */
145 | 038C316C1EE34A460071546D /* Sources */ = {
146 | isa = PBXSourcesBuildPhase;
147 | buildActionMask = 2147483647;
148 | files = (
149 | 038C31851EE34B6F0071546D /* RuleView.swift in Sources */,
150 | 038C31831EE34B5F0071546D /* ECAView.swift in Sources */,
151 | 038C31741EE34A460071546D /* AppDelegate.swift in Sources */,
152 | 038C31871EE35FE90071546D /* ECAModel.swift in Sources */,
153 | );
154 | runOnlyForDeploymentPostprocessing = 0;
155 | };
156 | /* End PBXSourcesBuildPhase section */
157 |
158 | /* Begin PBXVariantGroup section */
159 | 038C31771EE34A460071546D /* MainMenu.xib */ = {
160 | isa = PBXVariantGroup;
161 | children = (
162 | 038C31781EE34A460071546D /* Base */,
163 | );
164 | name = MainMenu.xib;
165 | sourceTree = "";
166 | };
167 | /* End PBXVariantGroup section */
168 |
169 | /* Begin XCBuildConfiguration section */
170 | 038C317B1EE34A460071546D /* Debug */ = {
171 | isa = XCBuildConfiguration;
172 | buildSettings = {
173 | ALWAYS_SEARCH_USER_PATHS = NO;
174 | CLANG_ANALYZER_NONNULL = YES;
175 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
176 | CLANG_CXX_LIBRARY = "libc++";
177 | CLANG_ENABLE_MODULES = YES;
178 | CLANG_ENABLE_OBJC_ARC = YES;
179 | CLANG_WARN_BOOL_CONVERSION = YES;
180 | CLANG_WARN_CONSTANT_CONVERSION = YES;
181 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
182 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
183 | CLANG_WARN_EMPTY_BODY = YES;
184 | CLANG_WARN_ENUM_CONVERSION = YES;
185 | CLANG_WARN_INFINITE_RECURSION = YES;
186 | CLANG_WARN_INT_CONVERSION = YES;
187 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
188 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
189 | CLANG_WARN_UNREACHABLE_CODE = YES;
190 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
191 | CODE_SIGN_IDENTITY = "-";
192 | COPY_PHASE_STRIP = NO;
193 | DEBUG_INFORMATION_FORMAT = dwarf;
194 | ENABLE_STRICT_OBJC_MSGSEND = YES;
195 | ENABLE_TESTABILITY = YES;
196 | GCC_C_LANGUAGE_STANDARD = gnu99;
197 | GCC_DYNAMIC_NO_PIC = NO;
198 | GCC_NO_COMMON_BLOCKS = YES;
199 | GCC_OPTIMIZATION_LEVEL = 0;
200 | GCC_PREPROCESSOR_DEFINITIONS = (
201 | "DEBUG=1",
202 | "$(inherited)",
203 | );
204 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
205 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
206 | GCC_WARN_UNDECLARED_SELECTOR = YES;
207 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
208 | GCC_WARN_UNUSED_FUNCTION = YES;
209 | GCC_WARN_UNUSED_VARIABLE = YES;
210 | MACOSX_DEPLOYMENT_TARGET = 10.12;
211 | MTL_ENABLE_DEBUG_INFO = YES;
212 | ONLY_ACTIVE_ARCH = YES;
213 | SDKROOT = macosx;
214 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
215 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
216 | };
217 | name = Debug;
218 | };
219 | 038C317C1EE34A460071546D /* Release */ = {
220 | isa = XCBuildConfiguration;
221 | buildSettings = {
222 | ALWAYS_SEARCH_USER_PATHS = NO;
223 | CLANG_ANALYZER_NONNULL = YES;
224 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
225 | CLANG_CXX_LIBRARY = "libc++";
226 | CLANG_ENABLE_MODULES = YES;
227 | CLANG_ENABLE_OBJC_ARC = YES;
228 | CLANG_WARN_BOOL_CONVERSION = YES;
229 | CLANG_WARN_CONSTANT_CONVERSION = YES;
230 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
231 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
232 | CLANG_WARN_EMPTY_BODY = YES;
233 | CLANG_WARN_ENUM_CONVERSION = YES;
234 | CLANG_WARN_INFINITE_RECURSION = YES;
235 | CLANG_WARN_INT_CONVERSION = YES;
236 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
237 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
238 | CLANG_WARN_UNREACHABLE_CODE = YES;
239 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
240 | CODE_SIGN_IDENTITY = "-";
241 | COPY_PHASE_STRIP = NO;
242 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
243 | ENABLE_NS_ASSERTIONS = NO;
244 | ENABLE_STRICT_OBJC_MSGSEND = YES;
245 | GCC_C_LANGUAGE_STANDARD = gnu99;
246 | GCC_NO_COMMON_BLOCKS = YES;
247 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
248 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
249 | GCC_WARN_UNDECLARED_SELECTOR = YES;
250 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
251 | GCC_WARN_UNUSED_FUNCTION = YES;
252 | GCC_WARN_UNUSED_VARIABLE = YES;
253 | MACOSX_DEPLOYMENT_TARGET = 10.12;
254 | MTL_ENABLE_DEBUG_INFO = NO;
255 | SDKROOT = macosx;
256 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
257 | };
258 | name = Release;
259 | };
260 | 038C317E1EE34A460071546D /* Debug */ = {
261 | isa = XCBuildConfiguration;
262 | buildSettings = {
263 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
264 | CODE_SIGN_ENTITLEMENTS = ECAExplorer.entitlements;
265 | COMBINE_HIDPI_IMAGES = YES;
266 | DEVELOPMENT_TEAM = VBYRKYS73S;
267 | INFOPLIST_FILE = ECA/Info.plist;
268 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
269 | PRODUCT_BUNDLE_IDENTIFIER = ch.seriot.ECA;
270 | PRODUCT_NAME = "$(TARGET_NAME)";
271 | SWIFT_VERSION = 3.0;
272 | };
273 | name = Debug;
274 | };
275 | 038C317F1EE34A460071546D /* Release */ = {
276 | isa = XCBuildConfiguration;
277 | buildSettings = {
278 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
279 | CODE_SIGN_ENTITLEMENTS = ECAExplorer.entitlements;
280 | COMBINE_HIDPI_IMAGES = YES;
281 | DEVELOPMENT_TEAM = VBYRKYS73S;
282 | INFOPLIST_FILE = ECA/Info.plist;
283 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
284 | PRODUCT_BUNDLE_IDENTIFIER = ch.seriot.ECA;
285 | PRODUCT_NAME = "$(TARGET_NAME)";
286 | SWIFT_VERSION = 3.0;
287 | };
288 | name = Release;
289 | };
290 | /* End XCBuildConfiguration section */
291 |
292 | /* Begin XCConfigurationList section */
293 | 038C316B1EE34A460071546D /* Build configuration list for PBXProject "ECAExplorer" */ = {
294 | isa = XCConfigurationList;
295 | buildConfigurations = (
296 | 038C317B1EE34A460071546D /* Debug */,
297 | 038C317C1EE34A460071546D /* Release */,
298 | );
299 | defaultConfigurationIsVisible = 0;
300 | defaultConfigurationName = Release;
301 | };
302 | 038C317D1EE34A460071546D /* Build configuration list for PBXNativeTarget "ECAExplorer" */ = {
303 | isa = XCConfigurationList;
304 | buildConfigurations = (
305 | 038C317E1EE34A460071546D /* Debug */,
306 | 038C317F1EE34A460071546D /* Release */,
307 | );
308 | defaultConfigurationIsVisible = 0;
309 | defaultConfigurationName = Release;
310 | };
311 | /* End XCConfigurationList section */
312 | };
313 | rootObject = 038C31681EE34A460071546D /* Project object */;
314 | }
315 |
--------------------------------------------------------------------------------
/ECAExplorer/ECA/Base.lproj/MainMenu.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
--------------------------------------------------------------------------------