Frequncy Window and loading implemented
This commit is contained in:
parent
ef111ee997
commit
086c8a0f94
@ -41,6 +41,8 @@
|
||||
E26246451EF5E64900EAA4A6 /* PDFDraw.xib in Resources */ = {isa = PBXBuildFile; fileRef = E26246431EF5E64900EAA4A6 /* PDFDraw.xib */; };
|
||||
E26246471EF6684B00EAA4A6 /* PDFItemViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E26246461EF6684B00EAA4A6 /* PDFItemViewController.xib */; };
|
||||
E26246491EF6688400EAA4A6 /* PDFItemViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E26246481EF6688400EAA4A6 /* PDFItemViewController.swift */; };
|
||||
E27A9DB51EF995C1000BC7A3 /* FrequencyGraph.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27A9DB41EF995C1000BC7A3 /* FrequencyGraph.swift */; };
|
||||
E27A9DB91EF99C20000BC7A3 /* FlippedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27A9DB81EF99C20000BC7A3 /* FlippedView.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -103,6 +105,8 @@
|
||||
E26246431EF5E64900EAA4A6 /* PDFDraw.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PDFDraw.xib; sourceTree = "<group>"; };
|
||||
E26246461EF6684B00EAA4A6 /* PDFItemViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PDFItemViewController.xib; sourceTree = "<group>"; };
|
||||
E26246481EF6688400EAA4A6 /* PDFItemViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PDFItemViewController.swift; sourceTree = "<group>"; };
|
||||
E27A9DB41EF995C1000BC7A3 /* FrequencyGraph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FrequencyGraph.swift; sourceTree = "<group>"; };
|
||||
E27A9DB81EF99C20000BC7A3 /* FlippedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlippedView.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -347,6 +351,8 @@
|
||||
E2268DFA1EF712D300C97726 /* Graph View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E27A9DB81EF99C20000BC7A3 /* FlippedView.swift */,
|
||||
E27A9DB41EF995C1000BC7A3 /* FrequencyGraph.swift */,
|
||||
E2218D511EF32AC6004298F6 /* GraphDetailsController.swift */,
|
||||
E262463C1EF55BCE00EAA4A6 /* GraphWindow.swift */,
|
||||
);
|
||||
@ -571,6 +577,8 @@
|
||||
E262463E1EF55BCE00EAA4A6 /* GraphWindow.swift in Sources */,
|
||||
E26246491EF6688400EAA4A6 /* PDFItemViewController.swift in Sources */,
|
||||
E2218D641EF45F37004298F6 /* LossDistributionPie.swift in Sources */,
|
||||
E27A9DB51EF995C1000BC7A3 /* FrequencyGraph.swift in Sources */,
|
||||
E27A9DB91EF99C20000BC7A3 /* FlippedView.swift in Sources */,
|
||||
E2218D571EF335E6004298F6 /* CollectionViewItemYear.swift in Sources */,
|
||||
E2218D521EF32AC6004298F6 /* GraphDetailsController.swift in Sources */,
|
||||
E2218D5D1EF3DD6F004298F6 /* CollectionViewItemMonth.swift in Sources */,
|
||||
|
||||
@ -87,8 +87,7 @@ extension CollectionViewMonth: NSCollectionViewDataSource {
|
||||
/*
|
||||
guard var logA = String(data: log.regularFileContents!, encoding: .utf8)?.components(separatedBy: "\n") else { return }
|
||||
*/
|
||||
guard var logA = FileOperations.load(log: log.regularFileContents! as NSData) else { return }
|
||||
logA.removeLast()
|
||||
guard let logA = FileOperations.load(log: log.regularFileContents! as NSData) else { return }
|
||||
item2.distribution = logA
|
||||
OperationQueue.main.addOperation {
|
||||
item2.loss.stringValue = "\(logA.count)"
|
||||
|
||||
24
Graphic Analysis 2/FlippedView.swift
Normal file
24
Graphic Analysis 2/FlippedView.swift
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// FlippedView.swift
|
||||
// Logger2
|
||||
//
|
||||
// Created by Kilian Hofmann on 03.08.16.
|
||||
// Copyright © 2016 Kilian Hofmann. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class FlippedView: NSView {
|
||||
|
||||
override func draw(_ dirtyRect: NSRect) {
|
||||
super.draw(dirtyRect)
|
||||
|
||||
// Drawing code here.
|
||||
}
|
||||
|
||||
override var isFlipped: Bool {
|
||||
get {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
263
Graphic Analysis 2/FrequencyGraph.swift
Normal file
263
Graphic Analysis 2/FrequencyGraph.swift
Normal file
@ -0,0 +1,263 @@
|
||||
//
|
||||
// GraphView.swift
|
||||
// Docsis Toolkit
|
||||
//
|
||||
// Created by Kilian Hofmann on 20.06.17.
|
||||
// Copyright © 2017 Kilian Hofmann. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class FrequencyGraph: NSView {
|
||||
let opQueue: OperationQueue = OperationQueue()
|
||||
// Constants
|
||||
static let graphSizeWithSeparator: Int = 109
|
||||
static let graphSize: Int = 108
|
||||
static let maxGraphSize: Int = 17300
|
||||
let zeroOffset: Double = 37
|
||||
// Path related
|
||||
var path: NSBezierPath = NSBezierPath.init()
|
||||
var threshold: NSBezierPath = NSBezierPath.init()
|
||||
var upstream: Bool = false
|
||||
var lastTime: Int = 0
|
||||
var lastTimeThreshold: Int = 0
|
||||
var timePaths: [NSBezierPath] = []
|
||||
var lossPaths: [NSBezierPath] = []
|
||||
var offset: Int = 0
|
||||
// Popover
|
||||
let popover: NSPopover = NSPopover()
|
||||
// Data
|
||||
var data: [String] = []
|
||||
var dataLoss: [String] = []
|
||||
var frequency: Double = 0.0
|
||||
// Cursor
|
||||
var cursor: NSBezierPath = NSBezierPath.init()
|
||||
// Superview
|
||||
var content: FlippedView!
|
||||
|
||||
init(upstream: Bool, frame: CGRect, superview: FlippedView) {
|
||||
super.init(frame: frame)
|
||||
self.upstream = upstream
|
||||
|
||||
let tracking: NSTrackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .mouseMoved, .activeInActiveApp, .inVisibleRect], owner: self, userInfo: nil)
|
||||
self.addTrackingArea(tracking)
|
||||
|
||||
popover.contentViewController = GraphDetailsController()
|
||||
|
||||
self.content = superview
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
}
|
||||
|
||||
override func draw(_ dirtyRect: NSRect) {
|
||||
|
||||
NSColor.white.setFill()
|
||||
NSRectFill(dirtyRect)
|
||||
|
||||
threshold.lineWidth = 0.5
|
||||
|
||||
if upstream {
|
||||
NSColor.red.set()
|
||||
threshold.stroke()
|
||||
} else {
|
||||
NSColor.blue.set()
|
||||
threshold.stroke()
|
||||
}
|
||||
|
||||
NSColor.black.set()
|
||||
path.lineWidth = 1
|
||||
path.stroke()
|
||||
|
||||
NSColor(red: 0, green: 0, blue: 0, alpha: 0.3).set()
|
||||
cursor.lineWidth = 2
|
||||
cursor.stroke()
|
||||
|
||||
for index in 0..<timePaths.count {
|
||||
timePaths[index].lineWidth = 0.5
|
||||
timePaths[index].stroke()
|
||||
}
|
||||
|
||||
for index in 0..<lossPaths.count {
|
||||
NSColor(red: 1, green: 0, blue: 0, alpha: 0.2).set()
|
||||
lossPaths[index].lineWidth = 2
|
||||
lossPaths[index].stroke()
|
||||
}
|
||||
}
|
||||
|
||||
override var isFlipped:Bool {
|
||||
get {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func initView() {
|
||||
// Setup Indicator
|
||||
// Zero line
|
||||
let zero: NSBezierPath = NSBezierPath()
|
||||
zero.move(to: NSPoint(x: 5, y: zeroOffset))
|
||||
zero.line(to: NSPoint(x: Int(FrequencyGraph.maxGraphSize-5), y: Int(zeroOffset)))
|
||||
self.timePaths.append(zero)
|
||||
// Add data points
|
||||
var lastWasSkipped: Bool = false
|
||||
for point in 0..<data.count {
|
||||
// Get values
|
||||
let level: Double? = Double(data[point].components(separatedBy: ";")[1])
|
||||
let threshold: Double? = Double(data[point].components(separatedBy: ";")[2])
|
||||
// Set path, skip if empty values (-)
|
||||
if level == nil || threshold == nil {
|
||||
skipPath()
|
||||
lastWasSkipped = true
|
||||
} else {
|
||||
if lastWasSkipped {
|
||||
restartPath(level!, threshold_level: threshold!)
|
||||
lastWasSkipped = false
|
||||
} else if point == 0 {
|
||||
// Get offset
|
||||
offset = 0
|
||||
let time: String = data[point].components(separatedBy: ";")[0]
|
||||
let hour: Int = Int(time.substring(to: time.index(time.startIndex, offsetBy: 2)))!
|
||||
let tensSeconds: Int = Int((time as NSString).substring(with: NSMakeRange(6, 1)))!
|
||||
offset = ((hour*60 + Int((time as NSString).substring(with: NSMakeRange(3, 2)))!) * 6 + tensSeconds) * 2
|
||||
// Set offset
|
||||
lastTime = offset
|
||||
lastTimeThreshold = offset
|
||||
addPath(level!, threshold_level: threshold!)
|
||||
} else {
|
||||
addPath(level!, threshold_level: threshold!)
|
||||
}
|
||||
}
|
||||
// Set connection loss zones
|
||||
for loss in 0..<dataLoss.count {
|
||||
if dataLoss[loss].substring(to: dataLoss[loss].index(dataLoss[loss].startIndex, offsetBy: 5)) == data[point].components(separatedBy: ";")[0].substring(to: data[point].components(separatedBy: ";")[0].index(data[point].components(separatedBy: ";")[0].startIndex, offsetBy: 5)) {
|
||||
|
||||
let lossPath: NSBezierPath = NSBezierPath()
|
||||
lossPath.move(to: NSPoint(x: CGFloat(10 + point*2 + offset), y: CGFloat(17)))
|
||||
lossPath.line(to: NSPoint(x: CGFloat(10 + point*2 + offset), y: CGFloat(FrequencyGraph.graphSize)))
|
||||
lossPaths.append(lossPath)
|
||||
}
|
||||
}
|
||||
// Set time scale
|
||||
if (point+offset/2) % 60 == 0 {
|
||||
// Time label
|
||||
let time: NSTextField = NSTextField(frame: NSMakeRect(CGFloat(10 + point*2 + offset), 0, 57, 17))
|
||||
time.drawsBackground = false
|
||||
time.isBezeled = false
|
||||
time.isBordered = false
|
||||
time.isSelectable = false
|
||||
time.stringValue = data[point].components(separatedBy: ";")[0]
|
||||
addSubview(time)
|
||||
// Time line
|
||||
let timePath: NSBezierPath = NSBezierPath()
|
||||
timePath.move(to: NSPoint(x: CGFloat(10 + point*2 + offset), y: CGFloat(5)))
|
||||
timePath.line(to: NSPoint(x: CGFloat(10 + point*2 + offset), y: CGFloat(107)))
|
||||
timePaths.append(timePath)
|
||||
}
|
||||
if (point+offset/2) % 100 == 0 {
|
||||
OperationQueue.main.addOperation {
|
||||
//self.indicator.increment(by: 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Put view in display
|
||||
OperationQueue.main.addOperation {
|
||||
|
||||
//self.indicator.isHidden = true
|
||||
self.content.addSubview(self)
|
||||
self.setNeedsDisplay(self.bounds)
|
||||
}
|
||||
OperationQueue.main.waitUntilAllOperationsAreFinished()
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Path related
|
||||
|
||||
func addPath(_ level: Double, threshold_level: Double) {
|
||||
if path.elementCount == 0 {
|
||||
path.move(to: NSMakePoint(CGFloat(10 + lastTime), CGFloat(level + zeroOffset)))
|
||||
} else {
|
||||
path.line(to: NSMakePoint(CGFloat(10 + lastTime), CGFloat(level + zeroOffset)))
|
||||
}
|
||||
|
||||
lastTime += 2
|
||||
|
||||
if threshold.elementCount == 0 {
|
||||
threshold.move(to: NSMakePoint(CGFloat(10 + lastTimeThreshold), CGFloat(threshold_level + zeroOffset)))
|
||||
} else {
|
||||
threshold.line(to: NSMakePoint(CGFloat(10 + lastTimeThreshold), CGFloat(threshold_level + zeroOffset)))
|
||||
}
|
||||
|
||||
lastTimeThreshold += 2
|
||||
}
|
||||
|
||||
func skipPath() {
|
||||
path.move(to: NSMakePoint(CGFloat(10 + lastTime), CGFloat(zeroOffset)))
|
||||
lastTime += 2
|
||||
threshold.move(to: NSMakePoint(CGFloat(10 + lastTimeThreshold), CGFloat(zeroOffset)))
|
||||
lastTimeThreshold += 2
|
||||
}
|
||||
|
||||
func restartPath(_ level: Double, threshold_level: Double) {
|
||||
path.move(to: NSMakePoint(CGFloat(10 + lastTime), CGFloat(level + 37)))
|
||||
lastTime += 2
|
||||
threshold.move(to: NSMakePoint(CGFloat(10 + lastTimeThreshold), CGFloat(threshold_level + zeroOffset)))
|
||||
lastTimeThreshold += 2
|
||||
}
|
||||
|
||||
// MARK: - Mouse Events
|
||||
|
||||
override func mouseMoved(with event: NSEvent) {
|
||||
cursor.removeAllPoints()
|
||||
popover.performClose(self)
|
||||
|
||||
let x: Int = Int(event.locationInWindow.x - 20 + (self.superview!.superview!.superview! as! NSScrollView).documentVisibleRect.origin.x)
|
||||
|
||||
cursor.move(to: NSPoint(x: x - x%2, y: 0))
|
||||
cursor.line(to: NSPoint(x: x - x%2, y: FrequencyGraph.graphSize))
|
||||
|
||||
setNeedsDisplay(self.bounds)
|
||||
}
|
||||
|
||||
override func mouseExited(with event: NSEvent) {
|
||||
cursor.removeAllPoints()
|
||||
popover.performClose(self)
|
||||
|
||||
setNeedsDisplay(self.bounds)
|
||||
}
|
||||
|
||||
override func mouseDown(with event: NSEvent) {
|
||||
let x: Int = Int(event.locationInWindow.x - 20 + (self.superview!.superview!.superview! as! NSScrollView).documentVisibleRect.origin.x)
|
||||
if 10 <= x && (x-10)/2 - offset/2 < data.count && (x-10)/2 - offset/2 >= 0 {
|
||||
|
||||
(popover.contentViewController! as! GraphDetailsController).freq_str = "\(roundToPlaces(1, input: frequency)) MHz"
|
||||
|
||||
(popover.contentViewController! as! GraphDetailsController).time_str = "\(data[(x-10) / 2 - offset / 2].components(separatedBy: ";")[0])"
|
||||
(popover.contentViewController! as! GraphDetailsController).power_str = "\(data[(x-10) / 2 - offset / 2].components(separatedBy: ";")[1]) dBmV"
|
||||
|
||||
if upstream {
|
||||
(popover.contentViewController! as! GraphDetailsController).snr_str = "\(data[(x-10) / 2 - offset / 2].components(separatedBy: ";")[2]) dBmV"
|
||||
(popover.contentViewController! as! GraphDetailsController).ranging_str = "\(data[(x-10) / 2 - offset / 2].components(separatedBy: ";")[3])"
|
||||
} else {
|
||||
(popover.contentViewController! as! GraphDetailsController).snr_str = "\(data[(x-10) / 2 - offset / 2].components(separatedBy: ";")[2]) dB"
|
||||
}
|
||||
|
||||
popover.show(relativeTo: NSMakeRect(CGFloat(x), 0, 2, CGFloat(FrequencyGraph.graphSize)), of: self, preferredEdge: .minY)
|
||||
}
|
||||
}
|
||||
|
||||
override func scrollWheel(with event: NSEvent) {
|
||||
super.scrollWheel(with: event)
|
||||
cursor.removeAllPoints()
|
||||
popover.performClose(self)
|
||||
|
||||
setNeedsDisplay(self.bounds)
|
||||
}
|
||||
|
||||
// MARK: - Helper
|
||||
|
||||
func roundToPlaces(_ places:Int, input: Double) -> Double {
|
||||
let divisor = pow(10.0, Double(places))
|
||||
return round(input * divisor) / divisor
|
||||
}
|
||||
}
|
||||
@ -10,7 +10,8 @@ import Cocoa
|
||||
|
||||
class GraphWindow: NSWindowController {
|
||||
|
||||
var collectionViewItem: CollectionViewItemMonth?
|
||||
var collectionViewItem: CollectionViewItemMonth!
|
||||
@IBOutlet var scrollView: NSScrollView!
|
||||
|
||||
override var windowNibName: String! {
|
||||
return "GraphWindow"
|
||||
@ -28,6 +29,47 @@ class GraphWindow: NSWindowController {
|
||||
override func windowDidLoad() {
|
||||
super.windowDidLoad()
|
||||
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
|
||||
|
||||
var upstreamFiles: [FileWrapper] = []
|
||||
var downstreamFiles: [FileWrapper] = []
|
||||
guard collectionViewItem.dayFW != nil else { return }
|
||||
for file in (collectionViewItem.dayFW?.fileWrappers)! {
|
||||
if file.key.contains("Upstream") {
|
||||
upstreamFiles.append(file.value)
|
||||
} else if file.key.contains("Downstream") {
|
||||
downstreamFiles.append(file.value)
|
||||
}
|
||||
}
|
||||
|
||||
let content: FlippedView = FlippedView(frame: NSMakeRect(0, 0, CGFloat(FrequencyGraph.maxGraphSize), CGFloat(((upstreamFiles.count + downstreamFiles.count) * FrequencyGraph.graphSizeWithSeparator)-1)))
|
||||
|
||||
scrollView.documentView = content
|
||||
|
||||
var numGraphs: Int = 0
|
||||
for item in upstreamFiles {
|
||||
let graph: FrequencyGraph = FrequencyGraph(upstream: true, frame: NSMakeRect(0, CGFloat(numGraphs * FrequencyGraph.graphSizeWithSeparator), CGFloat(FrequencyGraph.maxGraphSize), CGFloat(FrequencyGraph.graphSize)), superview: content)
|
||||
graph.dataLoss = collectionViewItem.distribution
|
||||
graph.data = FileOperations.loadUpstream(log: item.regularFileContents! as NSData)!
|
||||
let keyString: String = item.filename!.components(separatedBy: " ")[1]
|
||||
graph.frequency = Double(keyString.substring(to: keyString.index(keyString.endIndex, offsetBy: -4)))! / 1000000
|
||||
let opQueue: OperationQueue = OperationQueue()
|
||||
opQueue.addOperation {
|
||||
graph.initView()
|
||||
}
|
||||
numGraphs += 1
|
||||
}
|
||||
for item in downstreamFiles {
|
||||
let graph: FrequencyGraph = FrequencyGraph(upstream: false, frame: NSMakeRect(0, CGFloat(numGraphs * FrequencyGraph.graphSizeWithSeparator), CGFloat(FrequencyGraph.maxGraphSize), CGFloat(FrequencyGraph.graphSize)), superview: content)
|
||||
graph.dataLoss = collectionViewItem.distribution
|
||||
graph.data = FileOperations.loadDownstream(log: item.regularFileContents! as NSData)!
|
||||
let keyString: String = item.filename!.components(separatedBy: " ")[1]
|
||||
graph.frequency = Double(keyString.substring(to: keyString.index(keyString.endIndex, offsetBy: -4)))! / 1000000
|
||||
let opQueue: OperationQueue = OperationQueue()
|
||||
opQueue.addOperation {
|
||||
graph.initView()
|
||||
}
|
||||
numGraphs += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="GraphWindow" customModule="Graphic_Analysis_2" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="scrollView" destination="N7f-tq-7VU" id="e94-84-TFe"/>
|
||||
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
@ -21,6 +22,31 @@
|
||||
<view key="contentView" wantsLayer="YES" id="se5-gp-TjO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<scrollView fixedFrame="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" translatesAutoresizingMaskIntoConstraints="NO" id="N7f-tq-7VU">
|
||||
<rect key="frame" x="20" y="20" width="440" height="251"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<clipView key="contentView" ambiguous="YES" id="cR7-yI-MsB">
|
||||
<rect key="frame" x="1" y="1" width="438" height="249"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Aer-4J-rbN">
|
||||
<rect key="frame" x="0.0" y="0.0" width="423" height="234"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" verticalHuggingPriority="750" horizontal="YES" id="zjd-Nw-zvr">
|
||||
<rect key="frame" x="1" y="234" width="438" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="Aon-x3-aqt">
|
||||
<rect key="frame" x="423" y="1" width="16" height="249"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>424</string>
|
||||
<string>454</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
version 2.1
|
||||
build 424
|
||||
build 454
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user