diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index eba2ac26500b6b4f46cb166942dc112589215d5a..0000000000000000000000000000000000000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index e3f5b92725889d9990d684d465d7e48d4e6602b0..6fda9e88f53e238215b76d373ae7d982be4f69e1 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,12 @@ profiles.clj /resources/sample-dataset.db.trace.db /deploy/artifacts/* /resources/version.properties +xcuserdata +xcshareddata +*.xcworkspacedata +OSX/Metabase/jre +OSX/Resources/metabase.jar +OSX/build +/osx-artifacts +OSX/dsa_priv.pem +bin/config.json diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..d271c26dcc42be6d77d819ebd062bbb63a34ae67 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "OSX/Vendor/INAppStoreWindow"] + path = OSX/Vendor/INAppStoreWindow + url = git@github.com:indragiek/INAppStoreWindow.git diff --git a/OSX/Metabase.xcodeproj/project.pbxproj b/OSX/Metabase.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..6d8a9f5c4c6b6fb505fe4c1f1dfdb86dd56c21b6 --- /dev/null +++ b/OSX/Metabase.xcodeproj/project.pbxproj @@ -0,0 +1,673 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + D105B2241BB378C100A5D850 /* INAppStoreWindowSwizzling.c in Sources */ = {isa = PBXBuildFile; fileRef = D105B1F21BB378C100A5D850 /* INAppStoreWindowSwizzling.c */; }; + D105B2251BB378C100A5D850 /* INWindowBackgroundView+CoreUIRendering.m in Sources */ = {isa = PBXBuildFile; fileRef = D105B1F51BB378C100A5D850 /* INWindowBackgroundView+CoreUIRendering.m */; }; + D105B2261BB378C100A5D850 /* NSDocument+INAppStoreWindowFixes.m in Sources */ = {isa = PBXBuildFile; fileRef = D105B1F71BB378C100A5D850 /* NSDocument+INAppStoreWindowFixes.m */; }; + D105B2271BB378C100A5D850 /* INAppStoreWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = D105B1F91BB378C100A5D850 /* INAppStoreWindow.m */; }; + D105B2281BB378C100A5D850 /* INWindowButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D105B1FC1BB378C100A5D850 /* INWindowButton.m */; }; + D105B23C1BB5BE4A00A5D850 /* back_icon@1x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B2331BB5BE4A00A5D850 /* back_icon@1x.png */; }; + D105B23D1BB5BE4A00A5D850 /* back_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B2341BB5BE4A00A5D850 /* back_icon@2x.png */; }; + D105B23E1BB5BE4A00A5D850 /* forward_icon@1x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B2351BB5BE4A00A5D850 /* forward_icon@1x.png */; }; + D105B23F1BB5BE4A00A5D850 /* forward_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B2361BB5BE4A00A5D850 /* forward_icon@2x.png */; }; + D105B2401BB5BE4A00A5D850 /* link_icon@1x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B2371BB5BE4A00A5D850 /* link_icon@1x.png */; }; + D105B2411BB5BE4A00A5D850 /* link_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B2381BB5BE4A00A5D850 /* link_icon@2x.png */; }; + D105B2421BB5BE4A00A5D850 /* Logo_1024.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B2391BB5BE4A00A5D850 /* Logo_1024.png */; }; + D105B2431BB5BE4A00A5D850 /* refresh_icon@1x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B23A1BB5BE4A00A5D850 /* refresh_icon@1x.png */; }; + D105B2441BB5BE4A00A5D850 /* refresh_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B23B1BB5BE4A00A5D850 /* refresh_icon@2x.png */; }; + D121FD651BC5B2AF002101B0 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D121FD641BC5B2AF002101B0 /* Sparkle.framework */; }; + D121FD671BC5B375002101B0 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = D121FD641BC5B2AF002101B0 /* Sparkle.framework */; }; + D121FD691BC5B4E7002101B0 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = D121FD681BC5B4E7002101B0 /* dsa_pub.pem */; }; + D162C4A81BC87D2B009F678F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D162C49A1BC87D2B009F678F /* AppDelegate.m */; }; + D162C4A91BC87D2B009F678F /* MetabaseTask.m in Sources */ = {isa = PBXBuildFile; fileRef = D162C49C1BC87D2B009F678F /* MetabaseTask.m */; }; + D162C4AA1BC87D2B009F678F /* SettingsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D162C49E1BC87D2B009F678F /* SettingsManager.m */; }; + D162C4AB1BC87D2B009F678F /* TaskHealthChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = D162C4A01BC87D2B009F678F /* TaskHealthChecker.m */; }; + D162C4AE1BC87D2B009F678F /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = D162C4A51BC87D2B009F678F /* MainMenu.xib */; }; + D162C4AF1BC87D2B009F678F /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D162C4A71BC87D2B009F678F /* MainViewController.m */; }; + D18853BF1BB0CEC600D89803 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D18853BE1BB0CEC600D89803 /* Cocoa.framework */; }; + D18853C91BB0CEC600D89803 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D18853C71BB0CEC600D89803 /* InfoPlist.strings */; }; + D18853CB1BB0CEC600D89803 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D18853CA1BB0CEC600D89803 /* main.m */; }; + D18853CF1BB0CEC600D89803 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = D18853CD1BB0CEC600D89803 /* Credits.rtf */; }; + D18853D71BB0CEC600D89803 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D18853D61BB0CEC600D89803 /* Images.xcassets */; }; + D18853DE1BB0CEC600D89803 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D18853DD1BB0CEC600D89803 /* XCTest.framework */; }; + D18853DF1BB0CEC600D89803 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D18853BE1BB0CEC600D89803 /* Cocoa.framework */; }; + D18853F91BB0D37C00D89803 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D18853F81BB0D37B00D89803 /* WebKit.framework */; }; + D18854041BB0DC2600D89803 /* metabase.jar in Resources */ = {isa = PBXBuildFile; fileRef = D18854021BB0DB6000D89803 /* metabase.jar */; }; + D18855611BB1C8D700D89803 /* jre in Resources */ = {isa = PBXBuildFile; fileRef = D188555E1BB1C86F00D89803 /* jre */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + D18853E01BB0CEC600D89803 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D18853B31BB0CEC600D89803 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D18853BA1BB0CEC600D89803; + remoteInfo = Metabase; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + D121FD661BC5B364002101B0 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 12; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + D121FD671BC5B375002101B0 /* Sparkle.framework in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + D105B1F21BB378C100A5D850 /* INAppStoreWindowSwizzling.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = INAppStoreWindowSwizzling.c; sourceTree = "<group>"; }; + D105B1F31BB378C100A5D850 /* INAppStoreWindowSwizzling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INAppStoreWindowSwizzling.h; sourceTree = "<group>"; }; + D105B1F41BB378C100A5D850 /* INWindowBackgroundView+CoreUIRendering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "INWindowBackgroundView+CoreUIRendering.h"; sourceTree = "<group>"; }; + D105B1F51BB378C100A5D850 /* INWindowBackgroundView+CoreUIRendering.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "INWindowBackgroundView+CoreUIRendering.m"; sourceTree = "<group>"; }; + D105B1F61BB378C100A5D850 /* NSDocument+INAppStoreWindowFixes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDocument+INAppStoreWindowFixes.h"; sourceTree = "<group>"; }; + D105B1F71BB378C100A5D850 /* NSDocument+INAppStoreWindowFixes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDocument+INAppStoreWindowFixes.m"; sourceTree = "<group>"; }; + D105B1F81BB378C100A5D850 /* INAppStoreWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INAppStoreWindow.h; sourceTree = "<group>"; }; + D105B1F91BB378C100A5D850 /* INAppStoreWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = INAppStoreWindow.m; sourceTree = "<group>"; }; + D105B1FA1BB378C100A5D850 /* INAppStoreWindowCompatibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INAppStoreWindowCompatibility.h; sourceTree = "<group>"; }; + D105B1FB1BB378C100A5D850 /* INWindowButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INWindowButton.h; sourceTree = "<group>"; }; + D105B1FC1BB378C100A5D850 /* INWindowButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = INWindowButton.m; sourceTree = "<group>"; }; + D105B2331BB5BE4A00A5D850 /* back_icon@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_icon@1x.png"; sourceTree = "<group>"; }; + D105B2341BB5BE4A00A5D850 /* back_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_icon@2x.png"; sourceTree = "<group>"; }; + D105B2351BB5BE4A00A5D850 /* forward_icon@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "forward_icon@1x.png"; sourceTree = "<group>"; }; + D105B2361BB5BE4A00A5D850 /* forward_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "forward_icon@2x.png"; sourceTree = "<group>"; }; + D105B2371BB5BE4A00A5D850 /* link_icon@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "link_icon@1x.png"; sourceTree = "<group>"; }; + D105B2381BB5BE4A00A5D850 /* link_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "link_icon@2x.png"; sourceTree = "<group>"; }; + D105B2391BB5BE4A00A5D850 /* Logo_1024.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Logo_1024.png; sourceTree = "<group>"; }; + D105B23A1BB5BE4A00A5D850 /* refresh_icon@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "refresh_icon@1x.png"; sourceTree = "<group>"; }; + D105B23B1BB5BE4A00A5D850 /* refresh_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "refresh_icon@2x.png"; sourceTree = "<group>"; }; + D121FD641BC5B2AF002101B0 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = "<group>"; }; + D121FD681BC5B4E7002101B0 /* dsa_pub.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = dsa_pub.pem; sourceTree = "<group>"; }; + D162C4991BC87D2B009F678F /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; + D162C49A1BC87D2B009F678F /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; + D162C49B1BC87D2B009F678F /* MetabaseTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MetabaseTask.h; sourceTree = "<group>"; }; + D162C49C1BC87D2B009F678F /* MetabaseTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MetabaseTask.m; sourceTree = "<group>"; }; + D162C49D1BC87D2B009F678F /* SettingsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsManager.h; sourceTree = "<group>"; }; + D162C49E1BC87D2B009F678F /* SettingsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsManager.m; sourceTree = "<group>"; }; + D162C49F1BC87D2B009F678F /* TaskHealthChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TaskHealthChecker.h; sourceTree = "<group>"; }; + D162C4A01BC87D2B009F678F /* TaskHealthChecker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TaskHealthChecker.m; sourceTree = "<group>"; }; + D162C4A51BC87D2B009F678F /* MainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = "<group>"; }; + D162C4A61BC87D2B009F678F /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = "<group>"; }; + D162C4A71BC87D2B009F678F /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = "<group>"; }; + D18853BB1BB0CEC600D89803 /* Metabase.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Metabase.app; sourceTree = BUILT_PRODUCTS_DIR; }; + D18853BE1BB0CEC600D89803 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + D18853C11BB0CEC600D89803 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; + D18853C21BB0CEC600D89803 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + D18853C31BB0CEC600D89803 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + D18853C61BB0CEC600D89803 /* Metabase-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Metabase-Info.plist"; sourceTree = "<group>"; }; + D18853C81BB0CEC600D89803 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; }; + D18853CA1BB0CEC600D89803 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; + D18853CC1BB0CEC600D89803 /* Metabase-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Metabase-Prefix.pch"; sourceTree = "<group>"; }; + D18853CE1BB0CEC600D89803 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; }; + D18853D61BB0CEC600D89803 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ../Metabase/Images.xcassets; sourceTree = "<group>"; }; + D18853DC1BB0CEC600D89803 /* MetabaseTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MetabaseTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + D18853DD1BB0CEC600D89803 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + D18853F81BB0D37B00D89803 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + D18854021BB0DB6000D89803 /* metabase.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; path = metabase.jar; sourceTree = "<group>"; }; + D188555E1BB1C86F00D89803 /* jre */ = {isa = PBXFileReference; lastKnownFileType = folder; name = jre; path = Metabase/jre; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D18853B81BB0CEC600D89803 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D18853F91BB0D37C00D89803 /* WebKit.framework in Frameworks */, + D121FD651BC5B2AF002101B0 /* Sparkle.framework in Frameworks */, + D18853BF1BB0CEC600D89803 /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D18853D91BB0CEC600D89803 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D18853DF1BB0CEC600D89803 /* Cocoa.framework in Frameworks */, + D18853DE1BB0CEC600D89803 /* XCTest.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D105B1BD1BB378C100A5D850 /* Vendor */ = { + isa = PBXGroup; + children = ( + D121FD631BC5B2AF002101B0 /* Sparkle-1.11.0 */, + D105B1BE1BB378C100A5D850 /* INAppStoreWindow */, + ); + path = Vendor; + sourceTree = "<group>"; + }; + D105B1BE1BB378C100A5D850 /* INAppStoreWindow */ = { + isa = PBXGroup; + children = ( + D105B1F01BB378C100A5D850 /* INAppStoreWindow */, + ); + path = INAppStoreWindow; + sourceTree = "<group>"; + }; + D105B1F01BB378C100A5D850 /* INAppStoreWindow */ = { + isa = PBXGroup; + children = ( + D105B1F11BB378C100A5D850 /* Extensions */, + D105B1F81BB378C100A5D850 /* INAppStoreWindow.h */, + D105B1F91BB378C100A5D850 /* INAppStoreWindow.m */, + D105B1FA1BB378C100A5D850 /* INAppStoreWindowCompatibility.h */, + D105B1FB1BB378C100A5D850 /* INWindowButton.h */, + D105B1FC1BB378C100A5D850 /* INWindowButton.m */, + ); + path = INAppStoreWindow; + sourceTree = "<group>"; + }; + D105B1F11BB378C100A5D850 /* Extensions */ = { + isa = PBXGroup; + children = ( + D105B1F21BB378C100A5D850 /* INAppStoreWindowSwizzling.c */, + D105B1F31BB378C100A5D850 /* INAppStoreWindowSwizzling.h */, + D105B1F41BB378C100A5D850 /* INWindowBackgroundView+CoreUIRendering.h */, + D105B1F51BB378C100A5D850 /* INWindowBackgroundView+CoreUIRendering.m */, + D105B1F61BB378C100A5D850 /* NSDocument+INAppStoreWindowFixes.h */, + D105B1F71BB378C100A5D850 /* NSDocument+INAppStoreWindowFixes.m */, + ); + path = Extensions; + sourceTree = "<group>"; + }; + D105B2321BB5BE4A00A5D850 /* Images */ = { + isa = PBXGroup; + children = ( + D105B2331BB5BE4A00A5D850 /* back_icon@1x.png */, + D105B2341BB5BE4A00A5D850 /* back_icon@2x.png */, + D105B2351BB5BE4A00A5D850 /* forward_icon@1x.png */, + D105B2361BB5BE4A00A5D850 /* forward_icon@2x.png */, + D105B2371BB5BE4A00A5D850 /* link_icon@1x.png */, + D105B2381BB5BE4A00A5D850 /* link_icon@2x.png */, + D105B2391BB5BE4A00A5D850 /* Logo_1024.png */, + D105B23A1BB5BE4A00A5D850 /* refresh_icon@1x.png */, + D105B23B1BB5BE4A00A5D850 /* refresh_icon@2x.png */, + ); + path = Images; + sourceTree = "<group>"; + }; + D121FD631BC5B2AF002101B0 /* Sparkle-1.11.0 */ = { + isa = PBXGroup; + children = ( + D121FD641BC5B2AF002101B0 /* Sparkle.framework */, + ); + path = "Sparkle-1.11.0"; + sourceTree = "<group>"; + }; + D162C4981BC87D2B009F678F /* Backend */ = { + isa = PBXGroup; + children = ( + D162C4991BC87D2B009F678F /* AppDelegate.h */, + D162C49A1BC87D2B009F678F /* AppDelegate.m */, + D162C49B1BC87D2B009F678F /* MetabaseTask.h */, + D162C49C1BC87D2B009F678F /* MetabaseTask.m */, + D162C49D1BC87D2B009F678F /* SettingsManager.h */, + D162C49E1BC87D2B009F678F /* SettingsManager.m */, + D162C49F1BC87D2B009F678F /* TaskHealthChecker.h */, + D162C4A01BC87D2B009F678F /* TaskHealthChecker.m */, + ); + path = Backend; + sourceTree = "<group>"; + }; + D162C4A11BC87D2B009F678F /* UI */ = { + isa = PBXGroup; + children = ( + D162C4A51BC87D2B009F678F /* MainMenu.xib */, + D162C4A61BC87D2B009F678F /* MainViewController.h */, + D162C4A71BC87D2B009F678F /* MainViewController.m */, + ); + path = UI; + sourceTree = "<group>"; + }; + D18853B21BB0CEC600D89803 = { + isa = PBXGroup; + children = ( + D188555E1BB1C86F00D89803 /* jre */, + D18853C41BB0CEC600D89803 /* Metabase */, + D18854011BB0DB6000D89803 /* Resources */, + D105B1BD1BB378C100A5D850 /* Vendor */, + D18853BD1BB0CEC600D89803 /* Frameworks */, + D18853BC1BB0CEC600D89803 /* Products */, + ); + sourceTree = "<group>"; + }; + D18853BC1BB0CEC600D89803 /* Products */ = { + isa = PBXGroup; + children = ( + D18853BB1BB0CEC600D89803 /* Metabase.app */, + D18853DC1BB0CEC600D89803 /* MetabaseTests.xctest */, + ); + name = Products; + sourceTree = "<group>"; + }; + D18853BD1BB0CEC600D89803 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D18853F81BB0D37B00D89803 /* WebKit.framework */, + D18853BE1BB0CEC600D89803 /* Cocoa.framework */, + D18853DD1BB0CEC600D89803 /* XCTest.framework */, + D18853C01BB0CEC600D89803 /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = "<group>"; + }; + D18853C01BB0CEC600D89803 /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + D18853C11BB0CEC600D89803 /* AppKit.framework */, + D18853C21BB0CEC600D89803 /* CoreData.framework */, + D18853C31BB0CEC600D89803 /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = "<group>"; + }; + D18853C41BB0CEC600D89803 /* Metabase */ = { + isa = PBXGroup; + children = ( + D162C4981BC87D2B009F678F /* Backend */, + D162C4A11BC87D2B009F678F /* UI */, + D18853C51BB0CEC600D89803 /* Supporting Files */, + ); + path = Metabase; + sourceTree = "<group>"; + }; + D18853C51BB0CEC600D89803 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + D18853C61BB0CEC600D89803 /* Metabase-Info.plist */, + D18853C71BB0CEC600D89803 /* InfoPlist.strings */, + D18853CA1BB0CEC600D89803 /* main.m */, + D18853CC1BB0CEC600D89803 /* Metabase-Prefix.pch */, + D18853CD1BB0CEC600D89803 /* Credits.rtf */, + ); + name = "Supporting Files"; + sourceTree = "<group>"; + }; + D18854011BB0DB6000D89803 /* Resources */ = { + isa = PBXGroup; + children = ( + D18853D61BB0CEC600D89803 /* Images.xcassets */, + D105B2321BB5BE4A00A5D850 /* Images */, + D18854021BB0DB6000D89803 /* metabase.jar */, + D121FD681BC5B4E7002101B0 /* dsa_pub.pem */, + ); + path = Resources; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + D18853BA1BB0CEC600D89803 /* Metabase */ = { + isa = PBXNativeTarget; + buildConfigurationList = D18853EC1BB0CEC600D89803 /* Build configuration list for PBXNativeTarget "Metabase" */; + buildPhases = ( + D18853B71BB0CEC600D89803 /* Sources */, + D18853B81BB0CEC600D89803 /* Frameworks */, + D18853B91BB0CEC600D89803 /* Resources */, + D18854051BB1B90000D89803 /* Kill Existing Processes Listening on Ports 13000 - 14000 */, + D121FD661BC5B364002101B0 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Metabase; + productName = Metabase; + productReference = D18853BB1BB0CEC600D89803 /* Metabase.app */; + productType = "com.apple.product-type.application"; + }; + D18853DB1BB0CEC600D89803 /* MetabaseTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D18853EF1BB0CEC600D89803 /* Build configuration list for PBXNativeTarget "MetabaseTests" */; + buildPhases = ( + D18853D81BB0CEC600D89803 /* Sources */, + D18853D91BB0CEC600D89803 /* Frameworks */, + D18853DA1BB0CEC600D89803 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D18853E11BB0CEC600D89803 /* PBXTargetDependency */, + ); + name = MetabaseTests; + productName = MetabaseTests; + productReference = D18853DC1BB0CEC600D89803 /* MetabaseTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D18853B31BB0CEC600D89803 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0510; + ORGANIZATIONNAME = Metabase; + TargetAttributes = { + D18853BA1BB0CEC600D89803 = { + DevelopmentTeam = BR27ZJK7WW; + }; + D18853DB1BB0CEC600D89803 = { + TestTargetID = D18853BA1BB0CEC600D89803; + }; + }; + }; + buildConfigurationList = D18853B61BB0CEC600D89803 /* Build configuration list for PBXProject "Metabase" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = D18853B21BB0CEC600D89803; + productRefGroup = D18853BC1BB0CEC600D89803 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D18853BA1BB0CEC600D89803 /* Metabase */, + D18853DB1BB0CEC600D89803 /* MetabaseTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D18853B91BB0CEC600D89803 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D105B23D1BB5BE4A00A5D850 /* back_icon@2x.png in Resources */, + D121FD691BC5B4E7002101B0 /* dsa_pub.pem in Resources */, + D18855611BB1C8D700D89803 /* jre in Resources */, + D162C4AE1BC87D2B009F678F /* MainMenu.xib in Resources */, + D105B2401BB5BE4A00A5D850 /* link_icon@1x.png in Resources */, + D18854041BB0DC2600D89803 /* metabase.jar in Resources */, + D18853C91BB0CEC600D89803 /* InfoPlist.strings in Resources */, + D105B2431BB5BE4A00A5D850 /* refresh_icon@1x.png in Resources */, + D105B23F1BB5BE4A00A5D850 /* forward_icon@2x.png in Resources */, + D18853D71BB0CEC600D89803 /* Images.xcassets in Resources */, + D105B23E1BB5BE4A00A5D850 /* forward_icon@1x.png in Resources */, + D105B23C1BB5BE4A00A5D850 /* back_icon@1x.png in Resources */, + D18853CF1BB0CEC600D89803 /* Credits.rtf in Resources */, + D105B2421BB5BE4A00A5D850 /* Logo_1024.png in Resources */, + D105B2411BB5BE4A00A5D850 /* link_icon@2x.png in Resources */, + D105B2441BB5BE4A00A5D850 /* refresh_icon@2x.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D18853DA1BB0CEC600D89803 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + D18854051BB1B90000D89803 /* Kill Existing Processes Listening on Ports 13000 - 14000 */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Kill Existing Processes Listening on Ports 13000 - 14000"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /usr/bin/perl; + shellScript = "foreach(split(/\\n/, `lsof -i :13000-14000`)) {\n s/^[^\\d]+(\\d+).*$/$1/;\n m/^\\d+$/ && system('kill', $_);\n}"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D18853B71BB0CEC600D89803 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D162C4AB1BC87D2B009F678F /* TaskHealthChecker.m in Sources */, + D105B2261BB378C100A5D850 /* NSDocument+INAppStoreWindowFixes.m in Sources */, + D162C4AA1BC87D2B009F678F /* SettingsManager.m in Sources */, + D105B2251BB378C100A5D850 /* INWindowBackgroundView+CoreUIRendering.m in Sources */, + D105B2241BB378C100A5D850 /* INAppStoreWindowSwizzling.c in Sources */, + D18853CB1BB0CEC600D89803 /* main.m in Sources */, + D162C4AF1BC87D2B009F678F /* MainViewController.m in Sources */, + D105B2281BB378C100A5D850 /* INWindowButton.m in Sources */, + D105B2271BB378C100A5D850 /* INAppStoreWindow.m in Sources */, + D162C4A91BC87D2B009F678F /* MetabaseTask.m in Sources */, + D162C4A81BC87D2B009F678F /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D18853D81BB0CEC600D89803 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + D18853E11BB0CEC600D89803 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D18853BA1BB0CEC600D89803 /* Metabase */; + targetProxy = D18853E01BB0CEC600D89803 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + D18853C71BB0CEC600D89803 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + D18853C81BB0CEC600D89803 /* en */, + ); + name = InfoPlist.strings; + sourceTree = "<group>"; + }; + D18853CD1BB0CEC600D89803 /* Credits.rtf */ = { + isa = PBXVariantGroup; + children = ( + D18853CE1BB0CEC600D89803 /* en */, + ); + name = Credits.rtf; + sourceTree = "<group>"; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + D18853EA1BB0CEC600D89803 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.9; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + D18853EB1BB0CEC600D89803 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.9; + SDKROOT = macosx; + }; + name = Release; + }; + D18853ED1BB0CEC600D89803 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Vendor/Sparkle-1.11.0", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Metabase/Metabase-Prefix.pch"; + INFOPLIST_FILE = "Metabase/Metabase-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + D18853EE1BB0CEC600D89803 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + COMBINE_HIDPI_IMAGES = YES; + DEAD_CODE_STRIPPING = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Vendor/Sparkle-1.11.0", + ); + GCC_OPTIMIZATION_LEVEL = fast; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Metabase/Metabase-Prefix.pch"; + INFOPLIST_FILE = "Metabase/Metabase-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + D18853F01BB0CEC600D89803 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Metabase.app/Contents/MacOS/Metabase"; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(inherited)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Metabase/Metabase-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = "MetabaseTests/MetabaseTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + WRAPPER_EXTENSION = xctest; + }; + name = Debug; + }; + D18853F11BB0CEC600D89803 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Metabase.app/Contents/MacOS/Metabase"; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(inherited)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Metabase/Metabase-Prefix.pch"; + INFOPLIST_FILE = "MetabaseTests/MetabaseTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + WRAPPER_EXTENSION = xctest; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D18853B61BB0CEC600D89803 /* Build configuration list for PBXProject "Metabase" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D18853EA1BB0CEC600D89803 /* Debug */, + D18853EB1BB0CEC600D89803 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D18853EC1BB0CEC600D89803 /* Build configuration list for PBXNativeTarget "Metabase" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D18853ED1BB0CEC600D89803 /* Debug */, + D18853EE1BB0CEC600D89803 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D18853EF1BB0CEC600D89803 /* Build configuration list for PBXNativeTarget "MetabaseTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D18853F01BB0CEC600D89803 /* Debug */, + D18853F11BB0CEC600D89803 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D18853B31BB0CEC600D89803 /* Project object */; +} diff --git a/OSX/Metabase/Backend/AppDelegate.h b/OSX/Metabase/Backend/AppDelegate.h new file mode 100644 index 0000000000000000000000000000000000000000..6a5a0a3df9451f469dc8994ce25792d8353552bb --- /dev/null +++ b/OSX/Metabase/Backend/AppDelegate.h @@ -0,0 +1,17 @@ +// +// AppDelegate.h +// Metabase +// +// Created by Cam Saul on 9/21/15. +// Copyright (c) 2015 Metabase. All rights reserved. +// + +@import Cocoa; + +@interface AppDelegate : NSObject <NSApplicationDelegate> + ++ (AppDelegate *)instance; + +@property (readonly) NSUInteger port; + +@end diff --git a/OSX/Metabase/Backend/AppDelegate.m b/OSX/Metabase/Backend/AppDelegate.m new file mode 100644 index 0000000000000000000000000000000000000000..44966ed4840954ccd5b018dae52fede398dc6d0c --- /dev/null +++ b/OSX/Metabase/Backend/AppDelegate.m @@ -0,0 +1,102 @@ +// +// AppDelegate.m +// Metabase +// +// Created by Cam Saul on 9/21/15. +// Copyright (c) 2015 Metabase. All rights reserved. +// + +#import <Sparkle/Sparkle.h> + +#import "AppDelegate.h" +#import "MainViewController.h" +#import "MetabaseTask.h" +#import "TaskHealthChecker.h" + + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; + +@property (strong, nonatomic) MetabaseTask *task; +@property (strong, nonatomic) TaskHealthChecker *healthChecker; + +@end + + +static AppDelegate *sInstance = nil; + + +@implementation AppDelegate + ++ (AppDelegate *)instance { + return sInstance; +} + +- (id)init { + if (self = [super init]) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskTimedOut:) name:MetabaseTaskTimedOutNotification object:nil]; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + sInstance = self; + + [[SUUpdater sharedUpdater] checkForUpdatesInBackground]; + + self.task = [MetabaseTask task]; + self.healthChecker.port = self.task.port; + [self.healthChecker start]; +} + +- (void)applicationDidBecomeActive:(NSNotification *)notification { + // re-start the health checker if it's not checking like it should be : the HEALTH CHECKER HEALTH CHECKER + if (self.healthChecker.lastCheckTime) { + const CFTimeInterval timeSinceLastHealthCheck = CFAbsoluteTimeGetCurrent() - self.healthChecker.lastCheckTime; + if (timeSinceLastHealthCheck > 5.0f) { + NSLog(@"Last health check was %.0f ago, restarting health checker!", timeSinceLastHealthCheck); + [self.healthChecker start]; + } + } + // (re)start the health checker just to be extra double-safe it's still running +} + +- (void)applicationWillTerminate:(NSNotification *)notification { + self.task = nil; +} + + +#pragma mark - Notifications + +- (void)taskTimedOut:(NSNotification *)notification { + NSLog(@"Metabase task timed out. Restarting..."); + [self.healthChecker resetTimeout]; + self.task = [MetabaseTask task]; +} + + +#pragma mark - Getters / Setters + +- (TaskHealthChecker *)healthChecker { + if (!_healthChecker) { + _healthChecker = [[TaskHealthChecker alloc] init]; + } + return _healthChecker; +} + +- (void)setTask:(MetabaseTask *)task { + [_task terminate]; + _task = task; + [task launch]; +} + +- (NSUInteger)port { + return self.task.port; +} + +@end diff --git a/OSX/Metabase/Backend/MetabaseTask.h b/OSX/Metabase/Backend/MetabaseTask.h new file mode 100644 index 0000000000000000000000000000000000000000..fd15ae30fe732858b6b6e66def8f09dfe286a56a --- /dev/null +++ b/OSX/Metabase/Backend/MetabaseTask.h @@ -0,0 +1,19 @@ +// +// MetabaseTask.h +// Metabase +// +// Created by Cam Saul on 10/9/15. +// Copyright (c) 2015 Metabase. All rights reserved. +// + +@interface MetabaseTask : NSObject + +/// Create (and launch) a task to run the Metabase backend server. ++ (MetabaseTask *)task; + +- (void)launch; +- (void)terminate; + +- (NSUInteger)port; + +@end diff --git a/OSX/Metabase/Backend/MetabaseTask.m b/OSX/Metabase/Backend/MetabaseTask.m new file mode 100644 index 0000000000000000000000000000000000000000..7d79c0fff83e60be2e1557d5a8397d7bc33265ee --- /dev/null +++ b/OSX/Metabase/Backend/MetabaseTask.m @@ -0,0 +1,229 @@ +// +// MetabaseTask.m +// Metabase +// +// Created by Cam Saul on 10/9/15. +// Copyright (c) 2015 Metabase. All rights reserved. +// + +#import "MetabaseTask.h" + +#define ENABLE_JAR_UNPACKING 0 + +@interface MetabaseTask () +@property (strong, nonatomic) NSTask *task; +@property (strong, nonatomic) NSPipe *pipe; +@property (strong, nonatomic) NSFileHandle *readHandle; + +@property (strong, readonly) NSString *javaPath; +@property (strong, readonly) NSString *jarPath; +@property (strong, readonly) NSString *dbPath; + +#if ENABLE_JAR_UNPACKING + @property (strong, readonly) NSString *unpack200Path; +#endif + +@property (nonatomic) NSUInteger port; +@end + +@implementation MetabaseTask + ++ (MetabaseTask *)task { + return [[MetabaseTask alloc] init]; +} + + +#pragma mark - Lifecycle + +- (instancetype)init { + if (self = [super init]) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fileHandleCompletedRead:) name:NSFileHandleReadCompletionNotification object:nil]; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [self terminate]; +} + + +#pragma mark - Notifications + +- (void)fileHandleCompletedRead:(NSNotification *)notification { + if (!self.readHandle) return; + + __weak MetabaseTask *weakSelf = self; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + if (!weakSelf) return; + @try { + NSString *message = [[NSString alloc] initWithData:weakSelf.readHandle.availableData encoding:NSUTF8StringEncoding]; + // skip calls to health endpoint + if ([message rangeOfString:@"GET /api/health"].location == NSNotFound) { + // strip off the timestamp that comes back from the backend so we don't get double-timestamps when NSLog adds its own + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[\\d-:,\\s]+(.*$)" options:NSRegularExpressionAnchorsMatchLines|NSRegularExpressionAllowCommentsAndWhitespace error:nil]; + message = [regex stringByReplacingMatchesInString:message options:0 range:NSMakeRange(0, message.length) withTemplate:@"$1"]; + + // remove control codes used to color output + regex = [NSRegularExpression regularExpressionWithPattern:@"\\[\\d+m" options:0 error:nil]; + message = [regex stringByReplacingMatchesInString:message options:0 range:NSMakeRange(0, message.length) withTemplate:@""]; + + NSLog(@"%@", message); + } + } @catch (NSException *) {} + + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf.readHandle readInBackgroundAndNotify]; + }); + }); +} + + +#pragma mark - Local Methods + +#if ENABLE_JAR_UNPACKING +/// unpack the jars in the BG if needed the first time around +- (void)unpackJars { + [self.packedJarPaths enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSString *packedFilename, NSUInteger idx, BOOL *stop) { + NSString *jarName = [packedFilename stringByReplacingOccurrencesOfString:@".pack.gz" withString:@".jar"]; + + if (![[NSFileManager defaultManager] fileExistsAtPath:jarName]) { + NSLog(@"Unpacking %@ ->\n\t%@...", packedFilename, jarName); + NSTask *task = [[NSTask alloc] init]; + task.launchPath = self.unpack200Path; + task.arguments = @[packedFilename, jarName]; + [task launch]; + [task waitUntilExit]; + } + }]; +} +#endif + +- (void)deleteOldDBLockFilesIfNeeded { + NSString *lockFile = [self.dbPath stringByAppendingString:@".lock.db"]; + NSString *traceFile = [self.dbPath stringByAppendingString:@".trace.db"]; + + for (NSString *file in @[lockFile, traceFile]) { + if ([[NSFileManager defaultManager] fileExistsAtPath:file]) { + NSLog(@"Deleting %@...", file); + + NSError *error = nil; + [[NSFileManager defaultManager] removeItemAtPath:file error:&error]; + + if (error) { + NSLog(@"Error deleting %@: %@", file, error.localizedDescription); + } + } + } +} + +- (void)launch { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ + + #if ENABLE_JAR_UNPACKING + [self unpackJars]; + #endif + + [self deleteOldDBLockFilesIfNeeded]; + + NSLog(@"Starting MetabaseTask @ 0x%zx...", (size_t)self); + + self.task = [[NSTask alloc] init]; + self.task.launchPath = self.javaPath; + self.task.environment = @{@"MB_DB_FILE": self.dbPath, + @"MB_JETTY_PORT": @(self.port)}; + self.task.arguments = @[@"-jar", self.jarPath]; + + self.pipe = [NSPipe pipe]; + self.task.standardOutput = self.pipe; + self.task.standardError = self.pipe; + + __weak MetabaseTask *weakSelf = self; + self.task.terminationHandler = ^(NSTask *task){ + NSLog(@"\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Task terminated with exit code %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", task.terminationStatus); + dispatch_async(dispatch_get_main_queue(), ^{ + if ([[NSAlert alertWithMessageText:@"Fatal Error" defaultButton:@"Restart" alternateButton:@"Quit" otherButton:nil informativeTextWithFormat:@"The Metabase server terminated unexpectedly."] runModal] == NSAlertDefaultReturn) { + [weakSelf launch]; + } else { + exit(task.terminationStatus); + } + }); + }; + + self.readHandle = self.pipe.fileHandleForReading; + dispatch_async(dispatch_get_main_queue(), ^{ + [self.readHandle readInBackgroundAndNotify]; + }); + + NSLog(@"%@ -jar %@", self.javaPath, self.jarPath); + [self.task launch]; + }); +} + +- (void)terminate { + if (!self.task) return; // already dead + + NSLog(@"Killing MetabaseTask @ 0x%zx...", (size_t)self); + self.task = nil; + _port = 0; +} + + +#pragma mark - Getters / Setters + +- (void)setTask:(NSTask *)task { + self.pipe = nil; + [_task terminate]; + _task = task; +} + +- (void)setPipe:(NSPipe *)pipe { + self.readHandle = nil; + _pipe = pipe; +} + +- (void)setReadHandle:(NSFileHandle *)readHandle { + [_readHandle closeFile]; + _readHandle = readHandle; +} + +- (NSString *)javaPath { + return [[NSBundle mainBundle] pathForResource:@"java" ofType:nil inDirectory:@"jre/bin"]; +} + +- (NSString *)jarPath { + return [[NSBundle mainBundle] pathForResource:@"metabase" ofType:@"jar"]; +} + +- (NSString *)dbPath { + NSString *applicationSupportDir = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"Metabase"]; + if (![[NSFileManager defaultManager] fileExistsAtPath:applicationSupportDir]) { + NSError *error = nil; + [[NSFileManager defaultManager] createDirectoryAtPath:applicationSupportDir withIntermediateDirectories:YES attributes:nil error:&error]; + if (error) { + NSLog(@"Error creating %@: %@", applicationSupportDir, error.localizedDescription); + } + } + return [applicationSupportDir stringByAppendingPathComponent:@"metabase.db"]; +} + +- (NSUInteger)port { + if (!_port) { + srand((unsigned)time(NULL)); + _port = (rand() % 1000) + 13000; + NSLog(@"Using port %lu", _port); + } + return _port; +} + +#if ENABLE_JAR_UNPACKING +- (NSArray *)packedJarPaths { + return [[NSBundle mainBundle] pathsForResourcesOfType:@"pack.gz" inDirectory:@"jre/lib"]; +} + +- (NSString *)unpack200Path { + return [[NSBundle mainBundle] pathForResource:@"unpack200" ofType:nil inDirectory:@"jre/bin"]; +} +#endif + +@end diff --git a/OSX/Metabase/Backend/SettingsManager.h b/OSX/Metabase/Backend/SettingsManager.h new file mode 100644 index 0000000000000000000000000000000000000000..c21a5bdce24b0da3b324e8269ab526de1db54447 --- /dev/null +++ b/OSX/Metabase/Backend/SettingsManager.h @@ -0,0 +1,17 @@ +// +// SettingsManager.h +// Metabase +// +// Created by Cam Saul on 9/22/15. +// Copyright (c) 2015 Metabase. All rights reserved. +// + +NSString *LocalHostBaseURL(); + +@interface SettingsManager : NSObject + ++ (instancetype)instance; + +@property (copy) NSString *baseURL; + +@end diff --git a/OSX/Metabase/Backend/SettingsManager.m b/OSX/Metabase/Backend/SettingsManager.m new file mode 100644 index 0000000000000000000000000000000000000000..46b7f18d45be1a2773bdc5e406ef334e3841b3ad --- /dev/null +++ b/OSX/Metabase/Backend/SettingsManager.m @@ -0,0 +1,41 @@ +// +// SettingsManager.m +// Metabase +// +// Created by Cam Saul on 9/22/15. +// Copyright (c) 2015 Metabase. All rights reserved. +// + +#import "AppDelegate.h" +#import "SettingsManager.h" + +static SettingsManager *sSettingsManager = nil; + +static NSString * const BaseURLUserDefaultsKey = @"com.metabase.baseURL"; + +NSString *LocalHostBaseURL() { + return [NSString stringWithFormat:@"http://localhost:%lu", [AppDelegate instance].port]; +} + + +@implementation SettingsManager + ++ (instancetype)instance { + @synchronized(self) { + if (!sSettingsManager) sSettingsManager = [[SettingsManager alloc] init]; + } + return sSettingsManager; +} + +#pragma mark - Getters / Setters + +- (NSString *)baseURL { + return [[NSUserDefaults standardUserDefaults] objectForKey:BaseURLUserDefaultsKey]; +} + +- (void)setBaseURL:(NSString *)baseURL { + [[NSUserDefaults standardUserDefaults] setObject:[baseURL copy] forKey:BaseURLUserDefaultsKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +@end diff --git a/OSX/Metabase/Backend/TaskHealthChecker.h b/OSX/Metabase/Backend/TaskHealthChecker.h new file mode 100644 index 0000000000000000000000000000000000000000..629375d13a45b39fddb90a412a6a35b64709329d --- /dev/null +++ b/OSX/Metabase/Backend/TaskHealthChecker.h @@ -0,0 +1,23 @@ +// +// TaskHealthChecker.h +// Metabase +// +// Created by Cam Saul on 10/9/15. +// Copyright (c) 2015 Metabase. All rights reserved. +// + +static NSString * const MetabaseTaskBecameHealthyNotification = @"MetabaseTaskBecameHealthyNotification"; +static NSString * const MetabaseTaskBecameUnhealthyNotification = @"MetabaseTaskBecameUnhealthyNotification"; +static NSString * const MetabaseTaskTimedOutNotification = @"MetabaseTaskTimedOutNotification"; + +@interface TaskHealthChecker : NSObject + +@property () NSUInteger port; + +- (void)start; +- (void)stop; +- (void)resetTimeout; + +- (CFAbsoluteTime)lastCheckTime; + +@end diff --git a/OSX/Metabase/Backend/TaskHealthChecker.m b/OSX/Metabase/Backend/TaskHealthChecker.m new file mode 100644 index 0000000000000000000000000000000000000000..e1de91bded3d642987562dc3641e690dc31f09fb --- /dev/null +++ b/OSX/Metabase/Backend/TaskHealthChecker.m @@ -0,0 +1,149 @@ +// +// TaskHealthChecker.m +// Metabase +// +// Created by Cam Saul on 10/9/15. +// Copyright (c) 2015 Metabase. All rights reserved. +// + +#import "TaskHealthChecker.h" + +/// Check out health every this many seconds +static const CGFloat HealthCheckIntervalSeconds = 1.2f; + +/// This number should be lower than HealthCheckIntervalSeconds so requests don't end up piling up +static const CGFloat HealthCheckRequestTimeout = 0.25f; + +/// After this many seconds of being unhealthy, consider the task timed out so it can be killed +static const CFTimeInterval TimeoutIntervalSeconds = 10.0f; + +@interface TaskHealthChecker () +@property (strong, nonatomic) NSOperationQueue *healthCheckOperationQueue; +@property (strong, nonatomic) NSTimer *healthCheckTimer; + +@property (nonatomic) BOOL healthy; +@property CFAbsoluteTime lastHealthyTime; +@property CFAbsoluteTime lastCheckTime; + +/// Set this to YES after server has started successfully one time +/// we'll hold of on the whole killing the Metabase server until it launches one time, I guess +@property (nonatomic) BOOL hasEverBeenHealthy; +@end + +@implementation TaskHealthChecker + +- (void)dealloc { + [self stop]; +} + + +#pragma mark - Local Methods + +- (void)resetTimeout { + self.lastHealthyTime = CFAbsoluteTimeGetCurrent(); +} + +- (void)start { + NSLog(@"(re)starting health checker @ 0x%zx...", (size_t)self); + self.healthCheckOperationQueue = [[NSOperationQueue alloc] init]; + self.healthCheckOperationQueue.maxConcurrentOperationCount = 1; + + [self resetTimeout]; + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + self.healthCheckTimer = [NSTimer timerWithTimeInterval:HealthCheckIntervalSeconds target:self selector:@selector(checkHealth) userInfo:nil repeats:YES]; + self.healthCheckTimer.tolerance = HealthCheckIntervalSeconds / 2.0f; + [[NSRunLoop mainRunLoop] addTimer:self.healthCheckTimer forMode:NSRunLoopCommonModes]; + +// self.healthCheckTimer = [NSTimer scheduledTimerWithTimeInterval:HealthCheckIntervalSeconds target:self selector:@selector(checkHealth) userInfo:nil repeats:YES]; +// self.healthCheckTimer.tolerance = HealthCheckIntervalSeconds / 2.0f; // the timer doesn't need to fire exactly on the intervals, so give it a loose tolerance which will improve power savings, etc. + });} + + +- (void)stop { + self.healthCheckTimer = nil; + self.healthCheckOperationQueue = nil; +} + +- (void)checkHealth:(void(^)(BOOL healthy))completion { + self.lastCheckTime = CFAbsoluteTimeGetCurrent(); + + /// Cancel any pending checks so they don't pile up indefinitely + [self.healthCheckOperationQueue cancelAllOperations]; + + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%lu/api/health", self.port]] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:HealthCheckRequestTimeout]; + + [NSURLConnection sendAsynchronousRequest:request queue:self.healthCheckOperationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { + + if (connectionError) { + completion(NO); + return; + } + + NSError *jsonError = nil; + NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError]; + + if (jsonError) { + completion(NO); + return; + } + + completion([json[@"status"] isEqualToString:@"ok"]); + }]; +} + +- (void)checkHealth { + __weak TaskHealthChecker *weakSelf = self; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + [weakSelf checkHealth:^(BOOL healthy) { + if (!healthy) NSLog(@"😷"); + if (healthy && !weakSelf.healthy) NSLog(@"✅"); + + weakSelf.healthy = healthy; + }]; + }); +} + + +#pragma mark - Getters / Setters + +- (void)setHealthCheckTimer:(NSTimer *)healthCheckTimer { + [_healthCheckTimer invalidate]; + _healthCheckTimer = healthCheckTimer; +} + +- (void)setHealthCheckOperationQueue:(NSOperationQueue *)healthCheckOperationQueue { + [_healthCheckOperationQueue cancelAllOperations]; + _healthCheckOperationQueue = healthCheckOperationQueue; +} + +- (void)setHealthy:(BOOL)healthy { + if (healthy) { + self.lastHealthyTime = CFAbsoluteTimeGetCurrent(); + } else { + const CFTimeInterval timeSinceWasLastHealthy = CFAbsoluteTimeGetCurrent() - self.lastHealthyTime; + + if (timeSinceWasLastHealthy >= TimeoutIntervalSeconds) { + __weak TaskHealthChecker *weakSelf = self; + if (!self.hasEverBeenHealthy) { + NSLog(@"We've been waiting %.0f seconds, what's going on?", timeSinceWasLastHealthy); + return; + } + [[NSNotificationCenter defaultCenter] postNotificationName:MetabaseTaskTimedOutNotification object:weakSelf]; + } + } + + if (_healthy == healthy) return; + + _healthy = healthy; + NSLog(@"\n\n" + "+--------------------------------------------------------------------+\n" + "| Server status has transitioned to: %@ |\n" + "+--------------------------------------------------------------------+\n\n", (healthy ? @"HEALTHY " : @"NOT HEALTHY")); + + __weak TaskHealthChecker *weakSelf = self; + NSString *notification = healthy ? MetabaseTaskBecameHealthyNotification : MetabaseTaskBecameUnhealthyNotification; + [[NSNotificationCenter defaultCenter] postNotificationName:notification object:weakSelf]; +} + +@end diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Contents.json b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000000000000000000000000000000000..5727bad9d72448b6a0a4093c045fd41f8dfb745c --- /dev/null +++ b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "Logo_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "Logo_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "Logo_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "Logo_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "Logo_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "Logo_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "Logo_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "Logo_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "Logo_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "Logo_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_1024.png b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_1024.png new file mode 100644 index 0000000000000000000000000000000000000000..62b59a1be5b7868d73a76ed8fffe2bd1a937a14e Binary files /dev/null and b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_1024.png differ diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_128.png b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_128.png new file mode 100644 index 0000000000000000000000000000000000000000..0174f514d2326b21595a916559e1f582d69203c4 Binary files /dev/null and b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_128.png differ diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_16.png b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_16.png new file mode 100644 index 0000000000000000000000000000000000000000..332be62651f1a42cd44c648737ce38434c2b2596 Binary files /dev/null and b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_16.png differ diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_256.png b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_256.png new file mode 100644 index 0000000000000000000000000000000000000000..a045c036b365b72da1cf166fdba213aca9a8c2ca Binary files /dev/null and b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_256.png differ diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_32.png b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_32.png new file mode 100644 index 0000000000000000000000000000000000000000..52ed2b0079c9c4e76f9ed9c9c2601dc801ee10f8 Binary files /dev/null and b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_32.png differ diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_512.png b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_512.png new file mode 100644 index 0000000000000000000000000000000000000000..5df5cb0e0ff30b06ae69d0220a5cad023e4c3614 Binary files /dev/null and b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_512.png differ diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_64.png b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_64.png new file mode 100644 index 0000000000000000000000000000000000000000..d2f5af3699f4e7e81978687cfc55d557f3d6289a Binary files /dev/null and b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_64.png differ diff --git a/OSX/Metabase/Metabase-Info.plist b/OSX/Metabase/Metabase-Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..407b26d9b6712da50f33ba5a6b1fe0e197aa2a31 --- /dev/null +++ b/OSX/Metabase/Metabase-Info.plist @@ -0,0 +1,42 @@ +<?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>en</string> + <key>CFBundleExecutable</key> + <string>${EXECUTABLE_NAME}</string> + <key>CFBundleIconFile</key> + <string></string> + <key>CFBundleIdentifier</key> + <string>com.metabase.${PRODUCT_NAME:rfc1034identifier}</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.11.3.14</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>0.11.3.14</string> + <key>LSApplicationCategoryType</key> + <string>public.app-category.utilities</string> + <key>LSMinimumSystemVersion</key> + <string>${MACOSX_DEPLOYMENT_TARGET}</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2015 Metabase. All rights reserved.</string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> + <key>SUEnableAutomaticChecks</key> + <true/> + <key>SUFeedURL</key> + <string>https://s3-us-west-1.amazonaws.com/metabase-osx-releases/appcast.xml</string> + <key>SUPublicDSAKeyFile</key> + <string>dsa_pub.pem</string> +</dict> +</plist> diff --git a/OSX/Metabase/Metabase-Prefix.pch b/OSX/Metabase/Metabase-Prefix.pch new file mode 100644 index 0000000000000000000000000000000000000000..016cfddd1aabdb4debd63ef351b026231281881e --- /dev/null +++ b/OSX/Metabase/Metabase-Prefix.pch @@ -0,0 +1,9 @@ +// +// Prefix header +// +// The contents of this file are implicitly included at the beginning of every source file. +// + +#ifdef __OBJC__ + @import Cocoa; +#endif diff --git a/OSX/Metabase/UI/MainMenu.xib b/OSX/Metabase/UI/MainMenu.xib new file mode 100644 index 0000000000000000000000000000000000000000..14d7df6e1e5d62e91f63ebb21fdf27ebcd3b22db --- /dev/null +++ b/OSX/Metabase/UI/MainMenu.xib @@ -0,0 +1,311 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5053" systemVersion="13A603" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES"> + <dependencies> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5053"/> + <plugIn identifier="com.apple.WebKitIBPlugin" version="5053"/> + </dependencies> + <objects> + <customObject id="-2" userLabel="File's Owner" customClass="NSApplication"> + <connections> + <outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/> + </connections> + </customObject> + <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> + <customObject id="-3" userLabel="Application"/> + <customObject id="SvH-Fm-ua3" customClass="SUUpdater"/> + <customObject id="Voe-Tx-rLC" customClass="AppDelegate"> + <connections> + <outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/> + </connections> + </customObject> + <customObject id="YLy-65-1bz" customClass="NSFontManager"/> + <viewController title="MainViewController" nibName="" id="8au-ff-PAw" customClass="MainViewController"> + <connections> + <outlet property="backButtonCell" destination="lEo-fP-VyB" id="Liq-b8-nP9"/> + <outlet property="forwardButtonCell" destination="uF3-qn-F0a" id="eR7-ml-w4X"/> + <outlet property="linkButtonCell" destination="D9P-hg-lf8" id="G2L-cA-69g"/> + <outlet property="loadingView" destination="rgN-Vh-1hF" id="NCM-3X-yhL"/> + <outlet property="refreshButtonCell" destination="SSf-hM-lhY" id="xJE-83-OZr"/> + <outlet property="titleBarView" destination="Pem-Bq-pDs" id="nGc-wz-YES"/> + <outlet property="view" destination="EiT-Mj-1SZ" id="hOv-v9-VQo"/> + <outlet property="webView" destination="mhE-X5-FF6" id="MTz-Fg-4Di"/> + </connections> + </viewController> + <menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6"> + <items> + <menuItem title="Metabase" id="1Xt-HY-uBw"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Metabase" systemMenu="apple" id="uQy-DD-JDr"> + <items> + <menuItem title="Check for Updates..." id="deG-HF-Nuu"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="checkForUpdates:" target="SvH-Fm-ua3" id="hKn-lq-Ugp"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="45c-9m-ljg"/> + <menuItem title="Hide Metabase" keyEquivalent="h" id="Olw-nP-bQN"> + <connections> + <action selector="hide:" target="-1" id="PnN-Uc-m68"/> + </connections> + </menuItem> + <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO"> + <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> + <connections> + <action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/> + </connections> + </menuItem> + <menuItem title="Show All" id="Kd2-mp-pUS"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/> + <menuItem title="Quit Metabase" keyEquivalent="q" id="4sb-4s-VLi"> + <connections> + <action selector="terminate:" target="-1" id="Te7-pn-YzF"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Edit" id="5QF-Oa-p0T"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Edit" id="W48-6f-4Dl"> + <items> + <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg"> + <connections> + <action selector="undo:" target="-1" id="M6e-cu-g7V"/> + </connections> + </menuItem> + <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam"> + <connections> + <action selector="redo:" target="-1" id="oIA-Rs-6OD"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/> + <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG"> + <connections> + <action selector="cut:" target="-1" id="YJe-68-I9s"/> + </connections> + </menuItem> + <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU"> + <connections> + <action selector="copy:" target="-1" id="G1f-GL-Joy"/> + </connections> + </menuItem> + <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL"> + <connections> + <action selector="paste:" target="-1" id="UvS-8e-Qdg"/> + </connections> + </menuItem> + <menuItem title="Delete" id="pa3-QI-u2k"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="delete:" target="-1" id="0Mk-Ml-PaM"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Navigate" id="OrU-aO-QrS"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Navigate" id="Vm8-vh-NMO"> + <items> + <menuItem title="Back" keyEquivalent="" id="1tY-ia-YVu"> + <modifierMask key="keyEquivalentModifierMask" option="YES"/> + <connections> + <action selector="back:" target="8au-ff-PAw" id="E1u-Hv-xOJ"/> + </connections> + </menuItem> + <menuItem title="Forward" keyEquivalent="" id="XMU-vQ-kD4"> + <modifierMask key="keyEquivalentModifierMask" option="YES"/> + <connections> + <action selector="forward:" target="8au-ff-PAw" id="wGg-7M-OEs"/> + </connections> + </menuItem> + <menuItem title="Reload" keyEquivalent="r" id="4nb-4K-Z2y"> + <connections> + <action selector="reload:" target="8au-ff-PAw" id="LU6-rC-mFx"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="HRY-1F-Mgz"/> + <menuItem title="Copy Current URL to Clipboard" keyEquivalent="c" id="9UT-kQ-RV6"> + <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/> + <connections> + <action selector="copyURLToClipboard:" target="8au-ff-PAw" id="grb-Hc-gc4"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Window" id="aUF-d1-5bR"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo"> + <items> + <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV"> + <connections> + <action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/> + </connections> + </menuItem> + <menuItem title="Bring All to Front" id="LE2-aR-0XJ"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Help" id="wpr-3q-Mcd"> + <modifierMask key="keyEquivalentModifierMask"/> + </menuItem> + </items> + </menu> + <window title="Metabase" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="INAppStoreWindow"> + <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/> + <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> + <rect key="contentRect" x="335" y="390" width="1200" height="900"/> + <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/> + <value key="minSize" type="size" width="1000" height="800"/> + <view key="contentView" canDrawConcurrently="YES" id="EiT-Mj-1SZ"> + <rect key="frame" x="0.0" y="0.0" width="1200" height="900"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <webView canDrawConcurrently="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mhE-X5-FF6"> + <rect key="frame" x="0.0" y="0.0" width="1200" height="900"/> + <autoresizingMask key="autoresizingMask"/> + <webPreferences key="preferences" defaultFontSize="12" defaultFixedFontSize="12" plugInsEnabled="NO" javaEnabled="NO"> + <nil key="identifier"/> + </webPreferences> + <connections> + <outlet property="policyDelegate" destination="8au-ff-PAw" id="Ywf-Ex-Plw"/> + <outlet property="resourceLoadDelegate" destination="8au-ff-PAw" id="Rnd-KA-IRb"/> + </connections> + </webView> + <imageView canDrawConcurrently="YES" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="rgN-Vh-1hF"> + <rect key="frame" x="472" y="322" width="256" height="256"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <constraints> + <constraint firstAttribute="height" constant="256" id="Wi3-zz-jaD"/> + <constraint firstAttribute="width" constant="256" id="zOt-ub-YPO"/> + </constraints> + <imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="proportionallyDown" image="Logo_1024" id="wFY-0Y-m5p"/> + </imageView> + </subviews> + <constraints> + <constraint firstItem="mhE-X5-FF6" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" id="AbJ-I7-UJl"/> + <constraint firstItem="mhE-X5-FF6" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" id="JBU-I1-v0p"/> + <constraint firstAttribute="bottom" secondItem="mhE-X5-FF6" secondAttribute="bottom" id="OA1-e5-N7X"/> + <constraint firstAttribute="centerY" secondItem="rgN-Vh-1hF" secondAttribute="centerY" id="fMi-CB-Ih4"/> + <constraint firstAttribute="centerX" secondItem="rgN-Vh-1hF" secondAttribute="centerX" id="v6L-mJ-Sh5"/> + <constraint firstAttribute="trailing" secondItem="mhE-X5-FF6" secondAttribute="trailing" id="z4U-O6-LWv"/> + </constraints> + </view> + </window> + <customView id="Pem-Bq-pDs" userLabel="titleBarView"> + <rect key="frame" x="0.0" y="0.0" width="651" height="32"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <subviews> + <customView translatesAutoresizingMaskIntoConstraints="NO" id="V9v-oH-CLo"> + <rect key="frame" x="64" y="0.0" width="523" height="32"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <subviews> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="BVV-jo-b9C"> + <rect key="frame" x="229" y="8" width="64" height="17"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" enabled="NO" sendsActionOnEndEditing="YES" title="Metabase" id="Vvp-PZ-SY5"> + <font key="font" metaFont="system"/> + <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <button translatesAutoresizingMaskIntoConstraints="NO" id="dZP-Ul-oSB"> + <rect key="frame" x="0.0" y="0.0" width="24" height="32"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <constraints> + <constraint firstAttribute="width" constant="24" id="6zn-IR-p7a"/> + </constraints> + <buttonCell key="cell" type="bevel" bezelStyle="rounded" image="back_icon" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="lEo-fP-VyB"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system" size="23"/> + </buttonCell> + <connections> + <action selector="back:" target="8au-ff-PAw" id="MfY-gk-scw"/> + </connections> + </button> + <button translatesAutoresizingMaskIntoConstraints="NO" id="5Bt-VB-Dba"> + <rect key="frame" x="24" y="0.0" width="24" height="32"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <constraints> + <constraint firstAttribute="width" constant="24" id="cZI-NR-ghh"/> + </constraints> + <buttonCell key="cell" type="bevel" bezelStyle="rounded" image="forward_icon" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="uF3-qn-F0a"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system" size="23"/> + </buttonCell> + <connections> + <action selector="forward:" target="8au-ff-PAw" id="Hwj-Yo-Qtt"/> + </connections> + </button> + <button translatesAutoresizingMaskIntoConstraints="NO" id="HAI-2S-GZQ"> + <rect key="frame" x="48" y="0.0" width="24" height="32"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <constraints> + <constraint firstAttribute="width" constant="24" id="Bk3-9A-EeN"/> + </constraints> + <buttonCell key="cell" type="bevel" bezelStyle="rounded" image="refresh_icon" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="SSf-hM-lhY"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system" size="23"/> + </buttonCell> + <connections> + <action selector="reload:" target="8au-ff-PAw" id="y95-m6-iZ1"/> + </connections> + </button> + </subviews> + <constraints> + <constraint firstAttribute="centerY" secondItem="5Bt-VB-Dba" secondAttribute="centerY" id="2iz-ND-ODT"/> + <constraint firstAttribute="centerY" secondItem="HAI-2S-GZQ" secondAttribute="centerY" id="Efu-ly-nfn"/> + <constraint firstAttribute="centerY" secondItem="dZP-Ul-oSB" secondAttribute="centerY" id="FYl-6N-5zd"/> + <constraint firstAttribute="centerX" secondItem="BVV-jo-b9C" secondAttribute="centerX" id="LIX-0H-Hcn"/> + <constraint firstAttribute="centerY" secondItem="BVV-jo-b9C" secondAttribute="centerY" id="NaO-8y-1rD"/> + <constraint firstItem="dZP-Ul-oSB" firstAttribute="leading" secondItem="V9v-oH-CLo" secondAttribute="leading" id="P36-OS-GAI"/> + <constraint firstItem="HAI-2S-GZQ" firstAttribute="leading" secondItem="5Bt-VB-Dba" secondAttribute="trailing" id="cAU-bJ-DfV"/> + <constraint firstItem="5Bt-VB-Dba" firstAttribute="leading" secondItem="dZP-Ul-oSB" secondAttribute="trailing" id="pHA-7b-NC5"/> + </constraints> + </customView> + <button translatesAutoresizingMaskIntoConstraints="NO" id="XfF-w9-qlO"> + <rect key="frame" x="627" y="0.0" width="24" height="32"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <constraints> + <constraint firstAttribute="width" constant="24" id="O1n-dk-WFr"/> + </constraints> + <buttonCell key="cell" type="bevel" bezelStyle="rounded" image="link_icon" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="D9P-hg-lf8"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system" size="23"/> + </buttonCell> + <connections> + <action selector="copyURLToClipboard:" target="8au-ff-PAw" id="EEq-ZQ-Cwv"/> + </connections> + </button> + </subviews> + <constraints> + <constraint firstAttribute="trailing" secondItem="XfF-w9-qlO" secondAttribute="trailing" id="ScP-H6-pcc"/> + <constraint firstAttribute="bottom" secondItem="V9v-oH-CLo" secondAttribute="bottom" id="TY7-Sy-rWe"/> + <constraint firstItem="V9v-oH-CLo" firstAttribute="top" secondItem="Pem-Bq-pDs" secondAttribute="top" id="YVh-iR-cBq"/> + <constraint firstItem="V9v-oH-CLo" firstAttribute="leading" secondItem="Pem-Bq-pDs" secondAttribute="leading" constant="64" id="cEB-9C-Fnb"/> + <constraint firstAttribute="trailing" secondItem="V9v-oH-CLo" secondAttribute="trailing" constant="64" id="pcy-tI-xwH"/> + <constraint firstItem="XfF-w9-qlO" firstAttribute="top" secondItem="Pem-Bq-pDs" secondAttribute="top" id="rTc-5I-7Vt"/> + <constraint firstAttribute="bottom" secondItem="XfF-w9-qlO" secondAttribute="bottom" id="zqj-GW-B55"/> + </constraints> + </customView> + </objects> + <resources> + <image name="Logo_1024" width="1024" height="1024"/> + <image name="back_icon" width="10" height="15"/> + <image name="forward_icon" width="10" height="15"/> + <image name="link_icon" width="16" height="15"/> + <image name="refresh_icon" width="14" height="15"/> + </resources> +</document> diff --git a/OSX/Metabase/UI/MainViewController.h b/OSX/Metabase/UI/MainViewController.h new file mode 100644 index 0000000000000000000000000000000000000000..6739314eaf42920ef9b875492421ca5bd92c3ee8 --- /dev/null +++ b/OSX/Metabase/UI/MainViewController.h @@ -0,0 +1,13 @@ +// +// MainViewController.h +// Metabase +// +// Created by Cam Saul on 9/21/15. +// Copyright (c) 2015 Metabase. All rights reserved. +// + +@import Cocoa; + +@interface MainViewController : NSViewController + +@end diff --git a/OSX/Metabase/UI/MainViewController.m b/OSX/Metabase/UI/MainViewController.m new file mode 100644 index 0000000000000000000000000000000000000000..8acdcec61e381073104090354d3aa8f4314ed6f9 --- /dev/null +++ b/OSX/Metabase/UI/MainViewController.m @@ -0,0 +1,236 @@ +// +// MainViewController.m +// Metabase +// +// Created by Cam Saul on 9/21/15. +// Copyright (c) 2015 Metabase. All rights reserved. +// + +@import JavaScriptCore; +@import QuartzCore; +@import WebKit; + +#import "INAppStoreWindow.h" + +#import "MainViewController.h" +#import "SettingsManager.h" +#import "TaskHealthChecker.h" + +@interface MainViewController () +@property (weak) IBOutlet NSImageView *loadingView; +@property (weak) IBOutlet WebView *webView; +@property (strong) IBOutlet NSView *titleBarView; + +@property (weak) IBOutlet NSButtonCell *backButtonCell; +@property (weak) IBOutlet NSButtonCell *forwardButtonCell; +@property (weak) IBOutlet NSButtonCell *refreshButtonCell; +@property (weak) IBOutlet NSButtonCell *linkButtonCell; + +@property (strong, readonly) NSString *baseURL; + +@property (nonatomic) BOOL loading; + +@end + +@implementation MainViewController + +#pragma mark - Lifecycle + +- (void)awakeFromNib { + INAppStoreWindow *window = (INAppStoreWindow *)self.view.window; + window.titleBarHeight = self.titleBarView.bounds.size.height; + + self.view.wantsLayer = YES; + self.view.layer.backgroundColor = [NSColor whiteColor].CGColor; + + self.titleBarView.frame = window.titleBarView.bounds; + self.titleBarView.autoresizingMask = NSViewWidthSizable|NSViewHeightSizable; + [window.titleBarView addSubview:self.titleBarView]; + + self.loadingView.wantsLayer = YES; + self.loadingView.layer.masksToBounds = NO; + + self.webView.wantsLayer = YES; + + self.loadingView.animator.alphaValue = 0.0f; + self.webView.animator.alphaValue = 0.0f; + + dispatch_async(dispatch_get_main_queue(), ^{ + self.loading = YES; + }); + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskBecameHealthy:) name:MetabaseTaskBecameHealthyNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskBecameUnhealthy:) name:MetabaseTaskBecameUnhealthyNotification object:nil]; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + + +#pragma mark - Notifications + +- (void)taskBecameHealthy:(NSNotification *)notification { + dispatch_async(dispatch_get_main_queue(), ^{ + [self loadMainPage]; + dispatch_async(dispatch_get_main_queue(), ^{ + self.loading = NO; + }); + }); +} + +- (void)taskBecameUnhealthy:(NSNotification *)notification { + dispatch_async(dispatch_get_main_queue(), ^{ + self.loading = YES; + }); +} + + +#pragma mark - Local Methods + +- (void)loadMainPage { + NSLog(@"Connecting to Metabase instance at: %@", self.baseURL); + + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.baseURL]]; + request.cachePolicy = NSURLCacheStorageAllowedInMemoryOnly; + [self.webView.mainFrame loadRequest:request]; +} + +- (void)saveCSV:(NSString *)apiURL { + NSSavePanel *savePanel = [NSSavePanel savePanel]; + savePanel.allowedFileTypes = @[@"csv"]; + savePanel.allowsOtherFileTypes = NO; + savePanel.extensionHidden = NO; + savePanel.showsTagField = NO; + + NSString *downloadsDirectory = NSSearchPathForDirectoriesInDomains(NSDownloadsDirectory, NSUserDomainMask, YES)[0]; + savePanel.directoryURL = [NSURL URLWithString:downloadsDirectory]; + + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; + dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH_mm_ss"; + savePanel.nameFieldStringValue = [NSString stringWithFormat:@"query_result_%@", [dateFormatter stringFromDate:[NSDate date]]]; + + if ([savePanel runModal] == NSFileHandlingPanelOKButton) { + NSLog(@"Will save CSV at: %@", savePanel.URL); + + NSURL *url = [NSURL URLWithString:apiURL relativeToURL:[NSURL URLWithString:self.baseURL]]; + NSURLRequest *csvRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0f]; + [NSURLConnection sendAsynchronousRequest:csvRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { + NSError *writeError = nil; + [data writeToURL:savePanel.URL options:NSDataWritingAtomic error:&writeError]; + + dispatch_async(dispatch_get_main_queue(), ^{ + if (writeError) { + [[NSAlert alertWithError:writeError] runModal]; + } else { + [[NSAlert alertWithMessageText:@"Saved" defaultButton:@"Done" alternateButton:nil otherButton:nil informativeTextWithFormat:@"Your data has been saved."] runModal]; + } + }); + }]; + } +} + +- (void)injectJS { + JSContext *context = self.webView.mainFrame.javaScriptContext; + + // replace console.log with a function that calls NSLog so we can see the output + context[@"console"][@"log"] = ^(JSValue *message) { + NSLog(@"console.log: %@", message); + }; + + // custom functions for OS X integration are available to the frontend as properties of window.OSX + context[@"OSX"] = @{@"saveCSV": ^(JSValue *apiURL){ + [self saveCSV:apiURL.description]; + }}; +} + + +#pragma mark - Getters / Setters + +- (NSString *)baseURL { + return SettingsManager.instance.baseURL.length ? SettingsManager.instance.baseURL : LocalHostBaseURL(); +} + +- (void)setLoading:(BOOL)loading { + if (_loading == loading) return; + _loading = loading; + + if (loading) { + [self.loadingView.layer removeAllAnimations]; + + self.backButtonCell.enabled = self.forwardButtonCell.enabled = self.linkButtonCell.enabled = NO; + + self.webView.animator.alphaValue = 0.2f; + self.loadingView.animator.alphaValue = 1.0f; + + static const CGFloat LoadingViewScaleDuration = 2.5f; + static const CGFloat LoadingViewScaleMin = 0.65f; + static const CGFloat LoadingViewScaleMax = 1.0f; + + const CATransform3D min = CATransform3DTranslate(CATransform3DMakeScale(LoadingViewScaleMin, LoadingViewScaleMin, 1.0f), self.loadingView.bounds.size.width / 4.0f, self.loadingView.bounds.size.height / 4.0f, 0); + const CATransform3D max = CATransform3DMakeScale(LoadingViewScaleMax, LoadingViewScaleMax, 1.0f); + + CAKeyframeAnimation *scale = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; + scale.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + scale.values = @[[NSValue valueWithCATransform3D:min], + [NSValue valueWithCATransform3D:max], + [NSValue valueWithCATransform3D:min]]; + scale.duration = LoadingViewScaleDuration; + scale.repeatCount = HUGE_VALF; + + [self.loadingView.layer addAnimation:scale forKey:@"transform"]; + } else { + self.webView.animator.alphaValue = 1.0f; + self.loadingView.animator.alphaValue = 0.0f; + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self.loadingView.layer removeAllAnimations]; + }); + } +} + + +#pragma mark - Actions + +- (IBAction)back:(id)sender { + [self.webView goBack]; +} + +- (IBAction)forward:(id)sender { + [self.webView goForward]; +} + +- (IBAction)reload:(id)sender { + [self.webView.mainFrame reload]; +} + +- (IBAction)copyURLToClipboard:(id)sender { + [NSPasteboard.generalPasteboard declareTypes:@[NSStringPboardType] owner:nil]; + [NSPasteboard.generalPasteboard setString:self.webView.mainFrameURL forType:NSStringPboardType]; + + [[NSAlert alertWithMessageText:@"Link Copied" defaultButton:@"Ok" alternateButton:nil otherButton:nil informativeTextWithFormat:@"A link to this page has been copied to your clipboard."] runModal]; +} + + +#pragma mark - WebResourceLoadDelegate + +- (void)webView:(WebView *)sender resource:(id)identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource { + [self injectJS]; + + self.linkButtonCell.enabled = YES; + self.backButtonCell.enabled = self.webView.canGoBack; + self.forwardButtonCell.enabled = self.webView.canGoForward; +} + + +#pragma mark - WebPolicyDelegate + +- (void)webView:(WebView *)webView decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id<WebPolicyDecisionListener>)listener { + // Tell webkit window to open new links in browser + NSURL *url = actionInformation[WebActionOriginalURLKey]; + [[NSWorkspace sharedWorkspace] openURL:url]; + [listener ignore]; +} + +@end diff --git a/OSX/Metabase/en.lproj/Credits.rtf b/OSX/Metabase/en.lproj/Credits.rtf new file mode 100644 index 0000000000000000000000000000000000000000..46576ef211d18155ae1997e26c209a97ff1ec7ec --- /dev/null +++ b/OSX/Metabase/en.lproj/Credits.rtf @@ -0,0 +1,29 @@ +{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} +{\colortbl;\red255\green255\blue255;} +\paperw9840\paperh8400 +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural + +\f0\b\fs24 \cf0 Engineering: +\b0 \ + Some people\ +\ + +\b Human Interface Design: +\b0 \ + Some other people\ +\ + +\b Testing: +\b0 \ + Hopefully not nobody\ +\ + +\b Documentation: +\b0 \ + Whoever\ +\ + +\b With special thanks to: +\b0 \ + Mom\ +} diff --git a/OSX/Metabase/en.lproj/InfoPlist.strings b/OSX/Metabase/en.lproj/InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..477b28ff8f86a3158a71c4934fbd3a2456717d7a --- /dev/null +++ b/OSX/Metabase/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/OSX/Metabase/main.m b/OSX/Metabase/main.m new file mode 100644 index 0000000000000000000000000000000000000000..91c2e088fd9414fdf89e36160ca7e07bb2e38024 --- /dev/null +++ b/OSX/Metabase/main.m @@ -0,0 +1,14 @@ +// +// main.m +// Metabase +// +// Created by Cam Saul on 9/21/15. +// Copyright (c) 2015 Metabase. All rights reserved. +// + +@import Cocoa; + +int main(int argc, const char * argv[]) +{ + return NSApplicationMain(argc, argv); +} diff --git a/OSX/Resources/Images/Logo_1024.png b/OSX/Resources/Images/Logo_1024.png new file mode 100644 index 0000000000000000000000000000000000000000..62b59a1be5b7868d73a76ed8fffe2bd1a937a14e Binary files /dev/null and b/OSX/Resources/Images/Logo_1024.png differ diff --git a/OSX/Resources/Images/back_icon@1x.png b/OSX/Resources/Images/back_icon@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c29cd709903a3f3958a0df393e878796805c6c12 Binary files /dev/null and b/OSX/Resources/Images/back_icon@1x.png differ diff --git a/OSX/Resources/Images/back_icon@2x.png b/OSX/Resources/Images/back_icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..769022163ff2c01aa8c3ae57553e466dc2cf28b8 Binary files /dev/null and b/OSX/Resources/Images/back_icon@2x.png differ diff --git a/OSX/Resources/Images/forward_icon@1x.png b/OSX/Resources/Images/forward_icon@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..8f565cc6609123891b1b741c7e7a10815d93881b Binary files /dev/null and b/OSX/Resources/Images/forward_icon@1x.png differ diff --git a/OSX/Resources/Images/forward_icon@2x.png b/OSX/Resources/Images/forward_icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6d81433718b36a77155405f4e9c1bdeb8c1390c5 Binary files /dev/null and b/OSX/Resources/Images/forward_icon@2x.png differ diff --git a/OSX/Resources/Images/link_icon@1x.png b/OSX/Resources/Images/link_icon@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..3907aede09b85751aa15f14ab2f350c706f97904 Binary files /dev/null and b/OSX/Resources/Images/link_icon@1x.png differ diff --git a/OSX/Resources/Images/link_icon@2x.png b/OSX/Resources/Images/link_icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c3945c7b1a529fa13a70660d7b2e24893595d20c Binary files /dev/null and b/OSX/Resources/Images/link_icon@2x.png differ diff --git a/OSX/Resources/Images/refresh_icon@1x.png b/OSX/Resources/Images/refresh_icon@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..3abf33b1f294796ee2a4d06f459455b4c9ebee78 Binary files /dev/null and b/OSX/Resources/Images/refresh_icon@1x.png differ diff --git a/OSX/Resources/Images/refresh_icon@2x.png b/OSX/Resources/Images/refresh_icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..bbe59ca261023d09ca0126eb5d87be2408ef7f50 Binary files /dev/null and b/OSX/Resources/Images/refresh_icon@2x.png differ diff --git a/OSX/Resources/dsa_pub.pem b/OSX/Resources/dsa_pub.pem new file mode 100644 index 0000000000000000000000000000000000000000..15a5b55817abb995eb60a38d91245c6db7b1e67d --- /dev/null +++ b/OSX/Resources/dsa_pub.pem @@ -0,0 +1,36 @@ +-----BEGIN PUBLIC KEY----- +MIIGOjCCBC0GByqGSM44BAEwggQgAoICAQC7RwleUWvm0dR07ENWdXslkpZEs1e6 +B32itoDF1sm414IMzm2OoHspBqfGf3nQrDcZCW5cngtdLg5eS3x00Ssfdz8j+zHz +7sH5sMOipdUzxY0LS2qfOW0E5HKeSstLi5qpyE3IDOoQs57KRMeIlk0jPYml8rA7 +z1CTgEe18eSVcNgG2oceamNT9+dE5KleaOmuyV4RuPQF9n76kssMxN4qvP38AMI0 +MjEMKzwF8HsPS4ALPyf4S27ACNJU3Ws/clqDD9UWzsbB7gYtZYkqUjIJKbPqH1sm +ldGXQV5safL0f/kT4r7r+pSae669BeYEHG2k7JrOccQYfmL0arfhq5ucTYX3nd0v +XoEFjxmue4ofMpjgFBu/GstVbQl37oxihAwG7jxGbk9uzihGek6HfnKpbkVUAUiH +LhOvZXUJ6cO+FH4+KCBHsl9HwU0leiBLJ40xnNmWs42moG6LE4Hhs8Uco/9Vpj6R +0FWtoONiUtvXiAUY3EWQBRpb5uEnqD/r3HYTSpqwYWJkauOR0/DkvvIwmAi0NaO4 +bViiOz+luvn5p/6Le21qOdPopdArRXvQ3bSiopV7P0G6uwnQVtwS+A+rUfDZXSza +kNZBhK8lOILvk04kp+H4jjdeDGqOe/6HTBrkiVeQsQKla3h0V4ltRkVyBtfbNj6w +4asW5IsAKiCD2wIVAPy6gMCR+CERLTMkp4qoUYkpMiiXAoICABrhiisnOCqBSqR+ +m+4RRv2aE0pRSJ8XDfA7Kbzvssb31DP8p2AaQH9DZRVlaIEj/PUwO3HHAg6FeV3j +zLbDBkUHQKAlUb8JsonTthK6i7bC4ZfDge2JndLLvhi345P0dBL7gEZ/91jSYv7p +QF/bBZQ6FDp4Fpm5cqbg5FXaXJPneaqDd+VqgqZclgfihu92j+HvL6UhWtFdT/DB +JZTezjIJ4ox299vcEfCfhXXZYiNH6jv+guUt6reAVUobiQOk0QhQhNGXlSdUNs4f +NQ6ABE4RiB+iRy1PkoAZW4oZtBdBdmEKE8eC0skSqwoLf/XCljv/VySvO0ZO6bBg +FmZ3yhDgMLEwAzCnjGuaarBl5KxoN7Y7FBQjIugbYlNnr5nxDR5JcDqli+q/NEZT +qc6c3wf9rqEB9JxMxtkWWcqD7jJBIUiapUG3byieoDaaHi/cvxgnGTGI4nyDPge9 +hpPoP2WBU840wLDjZGxNyNQ78QwUHFIW5v0lPCwdIndZPQJq20z1YZ22lH7azOmB +NssDVVWSeqn2+DwG275nfK1Qv+V8ww/x0+8wYqOMjaGypMeS0g0MpBBJHZjVQ5Ku +NH+p9/QjvElk43tLq33cJYnFU/EPVqypE94kbH4bvHpOuysNtrbnvptXLEASO1V3 +sl0OAITKHVDZvvuDsXFPdhXQ9pUVA4ICBQACggIAQ7wfn+Fi2j1Ka5YPgTDf4LLA +4Z6vvdKcp3+gWnG0oX/X6n5fw//mu7tp2POMCEUm7ANsdTFUqKBfJvcYL15qZCUr +9D50prWTr4l7A+/NBv5qv/9STDEjccT7Vr5q0pJf6NOkNr/ydGB+0WZEBt/Cpnba +dAcAKm2BgSrfbb7gIXvOMm7/N+gfYqhYavWKeXv65k8bTfN9UX4odGnz4x0YfUe3 +OOank9ciKwqgDxPCY6mlqe6SuWrfboMimBrZzGUZKMqsAq8CNjH7wwv5XvGyLTMK +kqysS7fljvhmMf6A1adSxcn3vyckoXP0gHYE/pnn+lrQIpnRzC0x3pbxBYIrV7Qi +C93YtZAkH5UBIY2q3GL4YmNEIFI6jsJSWLVAxzxqaKbRe3M7FUtkCA2ae3WD+n8e +XNTCgZmQ0/4syz/3AH8aEaE1ujVE7K9J0Gl4GB8flrXOoKpmMC29zbOg5yuPG+N2 +w5uYmDmmRcOE3dYtSORVzNGObFg9bhvqa3H5zdasC6xCX9/XNFk6Cg693erYpDx3 +KKR6FgQN5qjSrVBBSn/+5JYFntGCs28CIuS3Fd+/Kp9/ZKExBT8AOfU1dXlNNnV3 +Ho77JDPPvJ/mCZwMDERrirU7K794qZ6EdSxzEaaj1VsEkG/nxOEo/3QmSGhr+sJU +2Rp2O05XdAhgjiObhhg= +-----END PUBLIC KEY----- diff --git a/OSX/Vendor/INAppStoreWindow b/OSX/Vendor/INAppStoreWindow new file mode 160000 index 0000000000000000000000000000000000000000..f91d83f42c159c9f64f4f37bfe1514ca94a651cf --- /dev/null +++ b/OSX/Vendor/INAppStoreWindow @@ -0,0 +1 @@ +Subproject commit f91d83f42c159c9f64f4f37bfe1514ca94a651cf diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Headers b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Headers new file mode 120000 index 0000000000000000000000000000000000000000..a177d2a6b92600696030834c319f5e1434f9ee6a --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Modules b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Modules new file mode 120000 index 0000000000000000000000000000000000000000..5736f3186e797b8b787748c9979d0fed3b0536c3 --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Modules @@ -0,0 +1 @@ +Versions/Current/Modules \ No newline at end of file diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/PrivateHeaders b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/PrivateHeaders new file mode 120000 index 0000000000000000000000000000000000000000..d8e56452691a4645a456259c344667485a974735 --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/PrivateHeaders @@ -0,0 +1 @@ +Versions/Current/PrivateHeaders \ No newline at end of file diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Resources b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Resources new file mode 120000 index 0000000000000000000000000000000000000000..953ee36f3bb709faf58a351e0b33c353e337c0a2 --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Sparkle b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Sparkle new file mode 120000 index 0000000000000000000000000000000000000000..b2c52731ea3d32dfd46bbd3bed06054190185822 --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Sparkle @@ -0,0 +1 @@ +Versions/Current/Sparkle \ No newline at end of file diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUAppcast.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUAppcast.h new file mode 100644 index 0000000000000000000000000000000000000000..8f3efc8e80e140b33081cbcc70f80ef338fb1699 --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUAppcast.h @@ -0,0 +1,26 @@ +// +// SUAppcast.h +// Sparkle +// +// Created by Andy Matuschak on 3/12/06. +// Copyright 2006 Andy Matuschak. All rights reserved. +// + +#ifndef SUAPPCAST_H +#define SUAPPCAST_H + +#import <Foundation/Foundation.h> +#import "SUExport.h" + +@class SUAppcastItem; +SU_EXPORT @interface SUAppcast : NSObject<NSURLDownloadDelegate> + +@property (copy) NSString *userAgentString; +@property (copy) NSDictionary *httpHeaders; + +- (void)fetchAppcastFromURL:(NSURL *)url completionBlock:(void (^)(NSError *))err; + +@property (readonly, copy) NSArray *items; +@end + +#endif diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h new file mode 100644 index 0000000000000000000000000000000000000000..e4c2a06df415794d29dfc7677215374a56182031 --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h @@ -0,0 +1,43 @@ +// +// SUAppcastItem.h +// Sparkle +// +// Created by Andy Matuschak on 3/12/06. +// Copyright 2006 Andy Matuschak. All rights reserved. +// + +#ifndef SUAPPCASTITEM_H +#define SUAPPCASTITEM_H + +#import <Foundation/Foundation.h> +#import "SUExport.h" + +SU_EXPORT @interface SUAppcastItem : NSObject +@property (copy, readonly) NSString *title; +@property (copy, readonly) NSDate *date; +@property (copy, readonly) NSString *itemDescription; +@property (strong, readonly) NSURL *releaseNotesURL; +@property (copy, readonly) NSString *DSASignature; +@property (copy, readonly) NSString *minimumSystemVersion; +@property (copy, readonly) NSString *maximumSystemVersion; +@property (strong, readonly) NSURL *fileURL; +@property (copy, readonly) NSString *versionString; +@property (copy, readonly) NSString *displayVersionString; +@property (copy, readonly) NSDictionary *deltaUpdates; +@property (strong, readonly) NSURL *infoURL; + +// Initializes with data from a dictionary provided by the RSS class. +- (instancetype)initWithDictionary:(NSDictionary *)dict; +- (instancetype)initWithDictionary:(NSDictionary *)dict failureReason:(NSString **)error; + +@property (getter=isDeltaUpdate, readonly) BOOL deltaUpdate; +@property (getter=isCriticalUpdate, readonly) BOOL criticalUpdate; + +// Returns the dictionary provided in initWithDictionary; this might be useful later for extensions. +@property (readonly, copy) NSDictionary *propertiesDictionary; + +- (NSURL *)infoURL; + +@end + +#endif diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUErrors.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUErrors.h new file mode 100644 index 0000000000000000000000000000000000000000..e624bb056c925a2f859141d2e61a66917113903b --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUErrors.h @@ -0,0 +1,44 @@ +// +// SUErrors.h +// Sparkle +// +// Created by C.W. Betts on 10/13/14. +// Copyright (c) 2014 Sparkle Project. All rights reserved. +// + +#ifndef SUERRORS_H +#define SUERRORS_H + +#import <Foundation/Foundation.h> +#import "SUExport.h" + +/** + * Error domain used by Sparkle + */ +SU_EXPORT extern NSString *const SUSparkleErrorDomain; + +typedef NS_ENUM(OSStatus, SUError) { + // Appcast phase errors. + SUAppcastParseError = 1000, + SUNoUpdateError = 1001, + SUAppcastError = 1002, + SURunningFromDiskImageError = 1003, + + // Downlaod phase errors. + SUTemporaryDirectoryError = 2000, + + // Extraction phase errors. + SUUnarchivingError = 3000, + SUSignatureError = 3001, + + // Installation phase errors. + SUFileCopyFailure = 4000, + SUAuthenticationFailure = 4001, + SUMissingUpdateError = 4002, + SUMissingInstallerToolError = 4003, + SURelaunchError = 4004, + SUInstallationError = 4005, + SUDowngradeError = 4006 +}; + +#endif diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUExport.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUExport.h new file mode 100644 index 0000000000000000000000000000000000000000..3e3f8a1646089b2a7d73f15efe565ffe976be03c --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUExport.h @@ -0,0 +1,18 @@ +// +// SUExport.h +// Sparkle +// +// Created by Jake Petroules on 2014-08-23. +// Copyright (c) 2014 Sparkle Project. All rights reserved. +// + +#ifndef SUEXPORT_H +#define SUEXPORT_H + +#ifdef BUILDING_SPARKLE +#define SU_EXPORT __attribute__((visibility("default"))) +#else +#define SU_EXPORT +#endif + +#endif diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUStandardVersionComparator.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUStandardVersionComparator.h new file mode 100644 index 0000000000000000000000000000000000000000..d7f2a48cf20ea050dca886b4dd870fe2a21689ad --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUStandardVersionComparator.h @@ -0,0 +1,38 @@ +// +// SUStandardVersionComparator.h +// Sparkle +// +// Created by Andy Matuschak on 12/21/07. +// Copyright 2007 Andy Matuschak. All rights reserved. +// + +#ifndef SUSTANDARDVERSIONCOMPARATOR_H +#define SUSTANDARDVERSIONCOMPARATOR_H + +#import <Foundation/Foundation.h> +#import "SUExport.h" +#import "SUVersionComparisonProtocol.h" + +/*! + Sparkle's default version comparator. + + This comparator is adapted from MacPAD, by Kevin Ballard. + It's "dumb" in that it does essentially string comparison, + in components split by character type. +*/ +SU_EXPORT @interface SUStandardVersionComparator : NSObject <SUVersionComparison> + +/*! + Returns a singleton instance of the comparator. +*/ ++ (SUStandardVersionComparator *)defaultComparator; + +/*! + Compares version strings through textual analysis. + + See the implementation for more details. +*/ +- (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; +@end + +#endif diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUUpdater.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUUpdater.h new file mode 100644 index 0000000000000000000000000000000000000000..ce07a142c40f1a65014e6a3622f75a004c3ec4de --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUUpdater.h @@ -0,0 +1,347 @@ +// +// SUUpdater.h +// Sparkle +// +// Created by Andy Matuschak on 1/4/06. +// Copyright 2006 Andy Matuschak. All rights reserved. +// + +#ifndef SUUPDATER_H +#define SUUPDATER_H + +#import <Foundation/Foundation.h> +#import "SUExport.h" +#import "SUVersionComparisonProtocol.h" +#import "SUVersionDisplayProtocol.h" + +@class SUUpdateDriver, SUAppcastItem, SUHost, SUAppcast; + +@protocol SUUpdaterDelegate; + +/*! + The main API in Sparkle for controlling the update mechanism. + + This class is used to configure the update paramters as well as manually + and automatically schedule and control checks for updates. + */ +SU_EXPORT @interface SUUpdater : NSObject + +@property (unsafe_unretained) IBOutlet id<SUUpdaterDelegate> delegate; + ++ (SUUpdater *)sharedUpdater; ++ (SUUpdater *)updaterForBundle:(NSBundle *)bundle; +- (instancetype)initForBundle:(NSBundle *)bundle; + +@property (readonly, strong) NSBundle *hostBundle; +@property (strong, readonly) NSBundle *sparkleBundle; + +@property BOOL automaticallyChecksForUpdates; + +@property NSTimeInterval updateCheckInterval; + +/*! + * The URL of the appcast used to download update information. + * + * This property must be called on the main thread. + */ +@property (copy) NSURL *feedURL; + +@property (nonatomic, copy) NSString *userAgentString; + +@property (copy) NSDictionary *httpHeaders; + +@property BOOL sendsSystemProfile; + +@property BOOL automaticallyDownloadsUpdates; + +/*! + Explicitly checks for updates and displays a progress dialog while doing so. + + This method is meant for a main menu item. + Connect any menu item to this action in Interface Builder, + and Sparkle will check for updates and report back its findings verbosely + when it is invoked. + */ +- (IBAction)checkForUpdates:(id)sender; + +/*! + Checks for updates, but does not display any UI unless an update is found. + + This is meant for programmatically initating a check for updates. That is, + it will display no UI unless it actually finds an update, in which case it + proceeds as usual. + + If the fully automated updating is turned on, however, this will invoke that + behavior, and if an update is found, it will be downloaded and prepped for + installation. + */ +- (void)checkForUpdatesInBackground; + +/*! + Returns the date of last update check. + + \returns \c nil if no check has been performed. + */ +@property (readonly, copy) NSDate *lastUpdateCheckDate; + +/*! + Begins a "probing" check for updates which will not actually offer to + update to that version. + + However, the delegate methods + SUUpdaterDelegate::updater:didFindValidUpdate: and + SUUpdaterDelegate::updaterDidNotFindUpdate: will be called, + so you can use that information in your UI. + */ +- (void)checkForUpdateInformation; + +/*! + Appropriately schedules or cancels the update checking timer according to + the preferences for time interval and automatic checks. + + This call does not change the date of the next check, + but only the internal NSTimer. + */ +- (void)resetUpdateCycle; + +@property (readonly) BOOL updateInProgress; + +@end + +// ----------------------------------------------------------------------------- +// SUUpdater Notifications for events that might be interesting to more than just the delegate +// The updater will be the notification object +// ----------------------------------------------------------------------------- +SU_EXPORT extern NSString *const SUUpdaterDidFinishLoadingAppCastNotification; +SU_EXPORT extern NSString *const SUUpdaterDidFindValidUpdateNotification; +SU_EXPORT extern NSString *const SUUpdaterDidNotFindUpdateNotification; +SU_EXPORT extern NSString *const SUUpdaterWillRestartNotification; +#define SUUpdaterWillRelaunchApplicationNotification SUUpdaterWillRestartNotification; +#define SUUpdaterWillInstallUpdateNotification SUUpdaterWillRestartNotification; + +// Key for the SUAppcastItem object in the SUUpdaterDidFindValidUpdateNotification userInfo +SU_EXPORT extern NSString *const SUUpdaterAppcastItemNotificationKey; +// Key for the SUAppcast object in the SUUpdaterDidFinishLoadingAppCastNotification userInfo +SU_EXPORT extern NSString *const SUUpdaterAppcastNotificationKey; + +// ----------------------------------------------------------------------------- +// SUUpdater Delegate: +// ----------------------------------------------------------------------------- + +/*! + Provides methods to control the behavior of an SUUpdater object. + */ +@protocol SUUpdaterDelegate <NSObject> +@optional + +/*! + Returns whether to allow Sparkle to pop up. + + For example, this may be used to prevent Sparkle from interrupting a setup assistant. + + \param updater The SUUpdater instance. + */ +- (BOOL)updaterMayCheckForUpdates:(SUUpdater *)updater; + +/*! + Returns additional parameters to append to the appcast URL's query string. + + This is potentially based on whether or not Sparkle will also be sending along the system profile. + + \param updater The SUUpdater instance. + \param sendingProfile Whether the system profile will also be sent. + + \return An array of dictionaries with keys: "key", "value", "displayKey", "displayValue", the latter two being specifically for display to the user. + */ +- (NSArray *)feedParametersForUpdater:(SUUpdater *)updater sendingSystemProfile:(BOOL)sendingProfile; + +/*! + Returns a custom appcast URL. + + Override this to dynamically specify the entire URL. + + \param updater The SUUpdater instance. + */ +- (NSString *)feedURLStringForUpdater:(SUUpdater *)updater; + +/*! + Returns whether Sparkle should prompt the user about automatic update checks. + + Use this to override the default behavior. + + \param updater The SUUpdater instance. + */ +- (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SUUpdater *)updater; + +/*! + Called after Sparkle has downloaded the appcast from the remote server. + + Implement this if you want to do some special handling with the appcast once it finishes loading. + + \param updater The SUUpdater instance. + \param appcast The appcast that was downloaded from the remote server. + */ +- (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast; + +/*! + Returns the item in the appcast corresponding to the update that should be installed. + + If you're using special logic or extensions in your appcast, + implement this to use your own logic for finding a valid update, if any, + in the given appcast. + + \param appcast The appcast that was downloaded from the remote server. + \param updater The SUUpdater instance. + */ +- (SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SUUpdater *)updater; + +/*! + Called when a valid update is found by the update driver. + + \param updater The SUUpdater instance. + \param item The appcast item corresponding to the update that is proposed to be installed. + */ +- (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)item; + +/*! + Called when a valid update is not found. + + \param updater The SUUpdater instance. + */ +- (void)updaterDidNotFindUpdate:(SUUpdater *)updater; + +/*! + Called immediately before downloading the specified update. + + \param updater The SUUpdater instance. + \param item The appcast item corresponding to the update that is proposed to be downloaded. + \param request The mutable URL request that will be used to download the update. + */ +- (void)updater:(SUUpdater *)updater willDownloadUpdate:(SUAppcastItem *)item withRequest:(NSMutableURLRequest *)request; + +/*! + Called after the specified update failed to download. + + \param updater The SUUpdater instance. + \param item The appcast item corresponding to the update that failed to download. + \param error The error generated by the failed download. + */ +- (void)updater:(SUUpdater *)updater failedToDownloadUpdate:(SUAppcastItem *)item error:(NSError *)error; + +/*! + Called immediately before installing the specified update. + + \param updater The SUUpdater instance. + \param item The appcast item corresponding to the update that is proposed to be installed. + */ +- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)item; + +/*! + Returns whether the relaunch should be delayed in order to perform other tasks. + + This is not called if the user didn't relaunch on the previous update, + in that case it will immediately restart. + + \param updater The SUUpdater instance. + \param item The appcast item corresponding to the update that is proposed to be installed. + \param invocation The invocation that must be completed before continuing with the relaunch. + + \return \c YES to delay the relaunch until \p invocation is invoked. + */ +- (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)item untilInvoking:(NSInvocation *)invocation; + +/*! + Returns whether the application should be relaunched at all. + + Some apps \b cannot be relaunched under certain circumstances. + This method can be used to explicitly prevent a relaunch. + + \param updater The SUUpdater instance. + */ +- (BOOL)updaterShouldRelaunchApplication:(SUUpdater *)updater; + +/*! + Called immediately before relaunching. + + \param updater The SUUpdater instance. + */ +- (void)updaterWillRelaunchApplication:(SUUpdater *)updater; + +/*! + Returns an object that compares version numbers to determine their arithmetic relation to each other. + + This method allows you to provide a custom version comparator. + If you don't implement this method or return \c nil, + the standard version comparator will be used. + + \sa SUStandardVersionComparator + + \param updater The SUUpdater instance. + */ +- (id<SUVersionComparison>)versionComparatorForUpdater:(SUUpdater *)updater; + +/*! + Returns an object that formats version numbers for display to the user. + + If you don't implement this method or return \c nil, + the standard version formatter will be used. + + \sa SUUpdateAlert + + \param updater The SUUpdater instance. + */ +- (id<SUVersionDisplay>)versionDisplayerForUpdater:(SUUpdater *)updater; + +/*! + Returns the path which is used to relaunch the client after the update is installed. + + The default is the path of the host bundle. + + \param updater The SUUpdater instance. + */ +- (NSString *)pathToRelaunchForUpdater:(SUUpdater *)updater; + +/*! + Called before an updater shows a modal alert window, + to give the host the opportunity to hide attached windows that may get in the way. + + \param updater The SUUpdater instance. + */ +- (void)updaterWillShowModalAlert:(SUUpdater *)updater; + +/*! + Called after an updater shows a modal alert window, + to give the host the opportunity to hide attached windows that may get in the way. + + \param updater The SUUpdater instance. + */ +- (void)updaterDidShowModalAlert:(SUUpdater *)updater; + +/*! + Called when an update is scheduled to be silently installed on quit. + + \param updater The SUUpdater instance. + \param item The appcast item corresponding to the update that is proposed to be installed. + \param invocation Can be used to trigger an immediate silent install and relaunch. + */ +- (void)updater:(SUUpdater *)updater willInstallUpdateOnQuit:(SUAppcastItem *)item immediateInstallationInvocation:(NSInvocation *)invocation; + +/*! + Calls after an update that was scheduled to be silently installed on quit has been canceled. + + \param updater The SUUpdater instance. + \param item The appcast item corresponding to the update that was proposed to be installed. + */ +- (void)updater:(SUUpdater *)updater didCancelInstallUpdateOnQuit:(SUAppcastItem *)item; + +/*! + Called after an update is aborted due to an error. + + \param updater The SUUpdater instance. + \param error The error that caused the abort + */ +- (void)updater:(SUUpdater *)updater didAbortWithError:(NSError *)error; + +@end + +#endif diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h new file mode 100644 index 0000000000000000000000000000000000000000..10c4266946bc7d40ce00761204ec41ee4e8cd37b --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h @@ -0,0 +1,30 @@ +// +// SUVersionComparisonProtocol.h +// Sparkle +// +// Created by Andy Matuschak on 12/21/07. +// Copyright 2007 Andy Matuschak. All rights reserved. +// + +#ifndef SUVERSIONCOMPARISONPROTOCOL_H +#define SUVERSIONCOMPARISONPROTOCOL_H + +#import <Cocoa/Cocoa.h> +#import "SUExport.h" + +/*! + Provides version comparison facilities for Sparkle. +*/ +@protocol SUVersionComparison + +/*! + An abstract method to compare two version strings. + + Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, + and NSOrderedSame if they are equivalent. +*/ +- (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; // *** MAY BE CALLED ON NON-MAIN THREAD! + +@end + +#endif diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h new file mode 100644 index 0000000000000000000000000000000000000000..97fae4c9096aa2b3eed92422a7aff1adde730f9d --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h @@ -0,0 +1,25 @@ +// +// SUVersionDisplayProtocol.h +// EyeTV +// +// Created by Uli Kusterer on 08.12.09. +// Copyright 2009 Elgato Systems GmbH. All rights reserved. +// + +#import <Cocoa/Cocoa.h> +#import "SUExport.h" + +/*! + Applies special display formatting to version numbers. +*/ +@protocol SUVersionDisplay + +/*! + Formats two version strings. + + Both versions are provided so that important distinguishing information + can be displayed while also leaving out unnecessary/confusing parts. +*/ +- (void)formatVersion:(NSString **)inOutVersionA andVersion:(NSString **)inOutVersionB; + +@end diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/Sparkle.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/Sparkle.h new file mode 100644 index 0000000000000000000000000000000000000000..7b48206441e70dd6e416c2492312893c308d6668 --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/Sparkle.h @@ -0,0 +1,25 @@ +// +// Sparkle.h +// Sparkle +// +// Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07) +// Copyright 2006 Andy Matuschak. All rights reserved. +// + +#ifndef SPARKLE_H +#define SPARKLE_H + +#import <Cocoa/Cocoa.h> + +// This list should include the shared headers. It doesn't matter if some of them aren't shared (unless +// there are name-space collisions) so we can list all of them to start with: + +#import <Sparkle/SUAppcast.h> +#import <Sparkle/SUAppcastItem.h> +#import <Sparkle/SUStandardVersionComparator.h> +#import <Sparkle/SUUpdater.h> +#import <Sparkle/SUVersionComparisonProtocol.h> +#import <Sparkle/SUVersionDisplayProtocol.h> +#import <Sparkle/SUErrors.h> + +#endif diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Modules/module.modulemap b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Modules/module.modulemap new file mode 100644 index 0000000000000000000000000000000000000000..af3fe6d05057de908fc235c400deeb27f1871472 --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module Sparkle { + umbrella header "Sparkle.h" + + export * + module * { export * } +} diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/PrivateHeaders/SUUnarchiver.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/PrivateHeaders/SUUnarchiver.h new file mode 100644 index 0000000000000000000000000000000000000000..6397fe71a1371d258b7995117636a48bfdc811a9 --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/PrivateHeaders/SUUnarchiver.h @@ -0,0 +1,35 @@ +// +// SUUnarchiver.h +// Sparkle +// +// Created by Andy Matuschak on 3/16/06. +// Copyright 2006 Andy Matuschak. All rights reserved. +// + +#ifndef SUUNARCHIVER_H +#define SUUNARCHIVER_H + +#import <Foundation/Foundation.h> + +@class SUHost; +@protocol SUUnarchiverDelegate; + +@interface SUUnarchiver : NSObject + +@property (copy, readonly) NSString *archivePath; +@property (copy, readonly) NSString *updateHostBundlePath; +@property (weak) id<SUUnarchiverDelegate> delegate; + ++ (SUUnarchiver *)unarchiverForPath:(NSString *)path updatingHostBundlePath:(NSString *)host; + +- (void)start; +@end + +@protocol SUUnarchiverDelegate <NSObject> +- (void)unarchiverDidFinish:(SUUnarchiver *)unarchiver; +- (void)unarchiverDidFail:(SUUnarchiver *)unarchiver; +@optional +- (void)unarchiver:(SUUnarchiver *)unarchiver extractedProgress:(double)progress; +@end + +#endif diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Info.plist b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..571db4f58c238399edb21bd4e2cf15be00beef49 --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Info.plist @@ -0,0 +1,54 @@ +<?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>BuildMachineOSBuild</key> + <string>15A244d</string> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>Autoupdate</string> + <key>CFBundleIconFile</key> + <string>AppIcon</string> + <key>CFBundleIdentifier</key> + <string>org.sparkle-project.Sparkle.Autoupdate</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.11.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleSupportedPlatforms</key> + <array> + <string>MacOSX</string> + </array> + <key>CFBundleVersion</key> + <string>1.11.0</string> + <key>DTCompiler</key> + <string>com.apple.compilers.llvm.clang.1_0</string> + <key>DTPlatformBuild</key> + <string>7A176x</string> + <key>DTPlatformVersion</key> + <string>GM</string> + <key>DTSDKBuild</key> + <string>15A244e</string> + <key>DTSDKName</key> + <string>macosx10.11</string> + <key>DTXcode</key> + <string>0700</string> + <key>DTXcodeBuild</key> + <string>7A176x</string> + <key>LSBackgroundOnly</key> + <string>1</string> + <key>LSMinimumSystemVersion</key> + <string>10.7</string> + <key>LSUIElement</key> + <string>1</string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> +</dict> +</plist> diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate new file mode 100755 index 0000000000000000000000000000000000000000..f4bfb8bef6f9df0f9e5997580cd68368c7f37e53 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/PkgInfo b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/PkgInfo new file mode 100644 index 0000000000000000000000000000000000000000..bd04210fb49f6032c3cd79559334dbe735a998ef --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPL???? \ No newline at end of file diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns new file mode 100644 index 0000000000000000000000000000000000000000..75c7c379f94c38d64cb160da894f3f41149cc34b Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib new file mode 100644 index 0000000000000000000000000000000000000000..30f3c2c4d1f6e3a63dd1df160ac5abec8443ced8 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..28c2c217250892ca0e65bc1b3a11c272d94626a5 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..a50d6bf22a8381a741c2e0dbceb1d7d913330728 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..8c349bd2b6c3302472c4b7c9738901e4eb388c78 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..fe50db5ca4d53df244a939041e8ef0c903b4124b Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..015c213ecf1f8fb449bdde13cae26c1f6bb2082c Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..d3c9f217d6a7b82cafe0579fdd659a1505d54acb Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..ee694079466290bb0a9a2ec01e38d2d8b8bea0e4 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..c7b221b12b2be92af6c5e97c70f754481fbb73e9 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..68ae6e0ae7b71ed89581d779caaedd8a27c39f3e Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..99955afc5a20cc0ce4ba3e6415334bf307a5cf50 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..faa546c86d66b947157270fe6bab01f99bbde633 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..d5df79da54e5b1a0b5850553a86644c34a5a3fd2 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..05a426d15c2900c117e662f8d7828db5fdde0b88 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..95923ee0bb2689fc1a3808b5394e0b9ea840bbec Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..d10801f5374464fd452424211f52104398815aaa Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..088cde6c2386511460fcf3235e39f340d4712636 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..69853a3f0a90f5e617036231e4d5e808007ec080 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..3cd694d59dd3db13f47bfbe6088b7aba34852e58 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..349f17fe3f5721bad05c7b7289fea17d4e52b0f8 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..38bb70dd077a32ecd7c70e465d06efb06b38ef84 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..889a6583e1f7ad676dfdebbb2ba680c97ddd2a70 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..e7e93079a70418c1d16bf1af6aaf208350d3dfa8 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..323bb70feb0c74f4bf25201586984df03b1491e8 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..74e17e44434dfae170ba9bcac2173c92cdaaf4d9 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..bf13d969296e651f021a72bdd8e588952d9b209b Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..49b68ce1e7b697bcefff97f7a62b6ca8365c74a9 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..d9229c96f1bc77843ea6d800e8f4a4f74e986078 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Info.plist b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..076941d5fff571ddd5a51dda5f2fb61756da33da --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,44 @@ +<?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>BuildMachineOSBuild</key> + <string>15A244d</string> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>Sparkle</string> + <key>CFBundleIdentifier</key> + <string>org.andymatuschak.Sparkle</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>Sparkle</string> + <key>CFBundlePackageType</key> + <string>FMWK</string> + <key>CFBundleShortVersionString</key> + <string>1.11.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleSupportedPlatforms</key> + <array> + <string>MacOSX</string> + </array> + <key>CFBundleVersion</key> + <string>1.11.0</string> + <key>DTCompiler</key> + <string>com.apple.compilers.llvm.clang.1_0</string> + <key>DTPlatformBuild</key> + <string>7A176x</string> + <key>DTPlatformVersion</key> + <string>GM</string> + <key>DTSDKBuild</key> + <string>15A244e</string> + <key>DTSDKName</key> + <string>macosx10.11</string> + <key>DTXcode</key> + <string>0700</string> + <key>DTXcodeBuild</key> + <string>7A176x</string> +</dict> +</plist> diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist new file mode 100644 index 0000000000000000000000000000000000000000..74db0ff07f8633e63dfce24340a89b87f255e489 --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist @@ -0,0 +1,228 @@ +<?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>ADP2,1</key> + <string>Developer Transition Kit</string> + <key>iMac1,1</key> + <string>iMac G3 (Rev A-D)</string> + <key>iMac4,1</key> + <string>iMac (Core Duo)</string> + <key>iMac4,2</key> + <string>iMac for Education (17 inch, Core Duo)</string> + <key>iMac5,1</key> + <string>iMac (Core 2 Duo, 17 or 20 inch, SuperDrive)</string> + <key>iMac5,2</key> + <string>iMac (Core 2 Duo, 17 inch, Combo Drive)</string> + <key>iMac6,1</key> + <string>iMac (Core 2 Duo, 24 inch, SuperDrive)</string> + <key>iMac8,1</key> + <string>iMac (Core 2 Duo, 20 or 24 inch, Early 2008 )</string> + <key>iMac9,1</key> + <string>iMac (Core 2 Duo, 20 or 24 inch, Early or Mid 2009 )</string> + <key>iMac10,1</key> + <string>iMac (Core 2 Duo, 21.5 or 27 inch, Late 2009 )</string> + <key>iMac11,1</key> + <string>iMac (Core i5 or i7, 27 inch Late 2009)</string> + <key>iMac11,2</key> + <string>iMac (Core i3 or i5, 27 inch Mid 2010)</string> + <key>iMac11,3</key> + <string>iMac (Core i5 or i7, 27 inch Mid 2010)</string> + <key>iMac12,1</key> + <string>iMac (Core i3 or i5 or i7, 21.5 inch Mid 2010 or Late 2011)</string> + <key>iMac12,2</key> + <string>iMac (Core i5 or i7, 27 inch Mid 2011)</string> + <key>iMac13,1</key> + <string>iMac (Core i3 or i5 or i7, 21.5 inch Late 2012 or Early 2013)</string> + <key>iMac13,2</key> + <string>iMac (Core i5 or i7, 27 inch Late 2012)</string> + <key>iMac14,1</key> + <string>iMac (Core i5, 21.5 inch Late 2013)</string> + <key>iMac14,2</key> + <string>iMac (Core i5 or i7, 27 inch Late 2013)</string> + <key>iMac14,3</key> + <string>iMac (Core i5 or i7, 21.5 inch Late 2013)</string> + <key>MacBook1,1</key> + <string>MacBook (Core Duo)</string> + <key>MacBook2,1</key> + <string>MacBook (Core 2 Duo)</string> + <key>MacBook4,1</key> + <string>MacBook (Core 2 Duo Feb 2008)</string> + <key>MacBook5,1</key> + <string>MacBook (Core 2 Duo, Late 2008, Unibody)</string> + <key>MacBook5,2</key> + <string>MacBook (Core 2 Duo, Early 2009, White)</string> + <key>MacBook6,1</key> + <string>MacBook (Core 2 Duo, Late 2009, Unibody)</string> + <key>MacBook7,1</key> + <string>MacBook (Core 2 Duo, Mid 2010, White)</string> + <key>MacBookAir1,1</key> + <string>MacBook Air (Core 2 Duo, 13 inch, Early 2008)</string> + <key>MacBookAir2,1</key> + <string>MacBook Air (Core 2 Duo, 13 inch, Mid 2009)</string> + <key>MacBookAir3,1</key> + <string>MacBook Air (Core 2 Duo, 11 inch, Late 2010)</string> + <key>MacBookAir3,2</key> + <string>MacBook Air (Core 2 Duo, 13 inch, Late 2010)</string> + <key>MacBookAir4,1</key> + <string>MacBook Air (Core i5 or i7, 11 inch, Mid 2011)</string> + <key>MacBookAir4,2</key> + <string>MacBook Air (Core i5 or i7, 13 inch, Mid 2011)</string> + <key>MacBookAir5,1</key> + <string>MacBook Air (Core i5 or i7, 11 inch, Mid 2012)</string> + <key>MacBookAir5,2</key> + <string>MacBook Air (Core i5 or i7, 13 inch, Mid 2012)</string> + <key>MacBookAir6,1</key> + <string>MacBook Air (Core i5 or i7, 11 inch, Mid 2013 or Early 2014)</string> + <key>MacBookAir6,2</key> + <string>MacBook Air (Core i5 or i7, 13 inch, Mid 2013 or Early 2014)</string> + <key>MacBookPro1,1</key> + <string>MacBook Pro Core Duo (15-inch)</string> + <key>MacBookPro1,2</key> + <string>MacBook Pro Core Duo (17-inch)</string> + <key>MacBookPro2,1</key> + <string>MacBook Pro Core 2 Duo (17-inch)</string> + <key>MacBookPro2,2</key> + <string>MacBook Pro Core 2 Duo (15-inch)</string> + <key>MacBookPro3,1</key> + <string>MacBook Pro Core 2 Duo (15-inch LED, Core 2 Duo)</string> + <key>MacBookPro3,2</key> + <string>MacBook Pro Core 2 Duo (17-inch HD, Core 2 Duo)</string> + <key>MacBookPro4,1</key> + <string>MacBook Pro (Core 2 Duo Feb 2008)</string> + <key>Macmini1,1</key> + <string>Mac Mini (Core Solo/Duo)</string> + <key>MacPro1,1</key> + <string>Mac Pro (four-core)</string> + <key>MacPro2,1</key> + <string>Mac Pro (eight-core)</string> + <key>MacPro3,1</key> + <string>Mac Pro (January 2008 4- or 8- core "Harpertown")</string> + <key>MacPro4,1</key> + <string>Mac Pro (March 2009)</string> + <key>MacPro5,1</key> + <string>Mac Pro (August 2010)</string> + <key>PowerBook1,1</key> + <string>PowerBook G3</string> + <key>PowerBook2,1</key> + <string>iBook G3</string> + <key>PowerBook2,2</key> + <string>iBook G3 (FireWire)</string> + <key>PowerBook2,3</key> + <string>iBook G3</string> + <key>PowerBook2,4</key> + <string>iBook G3</string> + <key>PowerBook3,1</key> + <string>PowerBook G3 (FireWire)</string> + <key>PowerBook3,2</key> + <string>PowerBook G4</string> + <key>PowerBook3,3</key> + <string>PowerBook G4 (Gigabit Ethernet)</string> + <key>PowerBook3,4</key> + <string>PowerBook G4 (DVI)</string> + <key>PowerBook3,5</key> + <string>PowerBook G4 (1GHz / 867MHz)</string> + <key>PowerBook4,1</key> + <string>iBook G3 (Dual USB, Late 2001)</string> + <key>PowerBook4,2</key> + <string>iBook G3 (16MB VRAM)</string> + <key>PowerBook4,3</key> + <string>iBook G3 Opaque 16MB VRAM, 32MB VRAM, Early 2003)</string> + <key>PowerBook5,1</key> + <string>PowerBook G4 (17 inch)</string> + <key>PowerBook5,2</key> + <string>PowerBook G4 (15 inch FW 800)</string> + <key>PowerBook5,3</key> + <string>PowerBook G4 (17-inch 1.33GHz)</string> + <key>PowerBook5,4</key> + <string>PowerBook G4 (15 inch 1.5/1.33GHz)</string> + <key>PowerBook5,5</key> + <string>PowerBook G4 (17-inch 1.5GHz)</string> + <key>PowerBook5,6</key> + <string>PowerBook G4 (15 inch 1.67GHz/1.5GHz)</string> + <key>PowerBook5,7</key> + <string>PowerBook G4 (17-inch 1.67GHz)</string> + <key>PowerBook5,8</key> + <string>PowerBook G4 (Double layer SD, 15 inch)</string> + <key>PowerBook5,9</key> + <string>PowerBook G4 (Double layer SD, 17 inch)</string> + <key>PowerBook6,1</key> + <string>PowerBook G4 (12 inch)</string> + <key>PowerBook6,2</key> + <string>PowerBook G4 (12 inch, DVI)</string> + <key>PowerBook6,3</key> + <string>iBook G4</string> + <key>PowerBook6,4</key> + <string>PowerBook G4 (12 inch 1.33GHz)</string> + <key>PowerBook6,5</key> + <string>iBook G4 (Early-Late 2004)</string> + <key>PowerBook6,7</key> + <string>iBook G4 (Mid 2005)</string> + <key>PowerBook6,8</key> + <string>PowerBook G4 (12 inch 1.5GHz)</string> + <key>PowerMac1,1</key> + <string>Power Macintosh G3 (Blue & White)</string> + <key>PowerMac1,2</key> + <string>Power Macintosh G4 (PCI Graphics)</string> + <key>PowerMac10,1</key> + <string>Mac Mini G4</string> + <key>PowerMac10,2</key> + <string>Mac Mini (Late 2005)</string> + <key>PowerMac11,2</key> + <string>Power Macintosh G5 (Late 2005)</string> + <key>PowerMac12,1</key> + <string>iMac G5 (iSight)</string> + <key>PowerMac2,1</key> + <string>iMac G3 (Slot-loading CD-ROM)</string> + <key>PowerMac2,2</key> + <string>iMac G3 (Summer 2000)</string> + <key>PowerMac3,1</key> + <string>Power Macintosh G4 (AGP Graphics)</string> + <key>PowerMac3,2</key> + <string>Power Macintosh G4 (AGP Graphics)</string> + <key>PowerMac3,3</key> + <string>Power Macintosh G4 (Gigabit Ethernet)</string> + <key>PowerMac3,4</key> + <string>Power Macintosh G4 (Digital Audio)</string> + <key>PowerMac3,5</key> + <string>Power Macintosh G4 (Quick Silver)</string> + <key>PowerMac3,6</key> + <string>Power Macintosh G4 (Mirrored Drive Door)</string> + <key>PowerMac4,1</key> + <string>iMac G3 (Early/Summer 2001)</string> + <key>PowerMac4,2</key> + <string>iMac G4 (Flat Panel)</string> + <key>PowerMac4,4</key> + <string>eMac</string> + <key>PowerMac4,5</key> + <string>iMac G4 (17-inch Flat Panel)</string> + <key>PowerMac5,1</key> + <string>Power Macintosh G4 Cube</string> + <key>PowerMac6,1</key> + <string>iMac G4 (USB 2.0)</string> + <key>PowerMac6,3</key> + <string>iMac G4 (20-inch Flat Panel)</string> + <key>PowerMac6,4</key> + <string>eMac (USB 2.0, 2005)</string> + <key>PowerMac7,2</key> + <string>Power Macintosh G5</string> + <key>PowerMac7,3</key> + <string>Power Macintosh G5</string> + <key>PowerMac8,1</key> + <string>iMac G5</string> + <key>PowerMac8,2</key> + <string>iMac G5 (Ambient Light Sensor)</string> + <key>PowerMac9,1</key> + <string>Power Macintosh G5 (Late 2005)</string> + <key>RackMac1,1</key> + <string>Xserve G4</string> + <key>RackMac1,2</key> + <string>Xserve G4 (slot-loading, cluster node)</string> + <key>RackMac3,1</key> + <string>Xserve G5</string> + <key>Xserve1,1</key> + <string>Xserve (Intel Xeon)</string> + <key>Xserve2,1</key> + <string>Xserve (January 2008 quad-core)</string> +</dict> +</plist> diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/SUStatus.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/SUStatus.nib new file mode 100644 index 0000000000000000000000000000000000000000..30f3c2c4d1f6e3a63dd1df160ac5abec8443ced8 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/SUStatus.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..0cf1e265080c12b7bb2389fefec8b0c6a24b88fe Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..e8f0030650d80acf990fb0255fbd427ccf1ba5db Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..108e6874c910e657fe8bdcbcb1340247c5d3aa7c Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..28c2c217250892ca0e65bc1b3a11c272d94626a5 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..fcc6a46fc9cc82425fead6472d02cf1ab2195680 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..74c8abc63bad07200e4c920a8063880c214fea8a Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..53d7446a68ea650c75ad38bf7e7b2f16a0e98b24 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..a50d6bf22a8381a741c2e0dbceb1d7d913330728 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..60949aadf189ac984bbeaf4a37c2630a36c10225 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..f514a4a01a2a9043db1c463cab51aa1d17a780ed Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..a2a56b975989518edf08c9b1f8d7b4ab585e5e32 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..8c349bd2b6c3302472c4b7c9738901e4eb388c78 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..204098fc18f0926e7960f1d941afae862c171a04 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..c97a4406cf0690212fec612e1ed8dcdf3081902a Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..d62b5720e806a5056f4e8b8ebc7977dfc373083d Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..fe50db5ca4d53df244a939041e8ef0c903b4124b Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..ed654db41e6ff1182d706205c57bdb8d0b06cc72 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..45c7fde67eb9142223f9ba1cf1e89ecf379ae12c Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..b79f6bedb59c785fe0de33d95af729111725c10b Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..015c213ecf1f8fb449bdde13cae26c1f6bb2082c Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..df090b491f3131ac3c4653777badcc9b988c4f8a Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..087db77607a6b71cbd20b84f74195ffa359a945e Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..76a955118b2bc4e4ea99059a3223645ce780d535 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..d3c9f217d6a7b82cafe0579fdd659a1505d54acb Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..6018bc31e1c93456680f4a4ccf24e3ce12d90111 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..c35ca148e48d020cf17d5c978de377ff759695ab Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..e6df30cd7d1d2a3d8f9e1387369af0b9ecce2675 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..ee694079466290bb0a9a2ec01e38d2d8b8bea0e4 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..5b0007f0bb463ed4c093d305bbe2ce13752e715d Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..7ed6802064ebdeff19d8d7cdb5bedf225bb82024 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..f7f8a502e9ced683e1de838232fccb06b74503f1 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..c7b221b12b2be92af6c5e97c70f754481fbb73e9 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr_CA.lproj b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr_CA.lproj new file mode 120000 index 0000000000000000000000000000000000000000..f9834a395ef84f59827ee1aea933b0d15ff52b9d --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr_CA.lproj @@ -0,0 +1 @@ +fr.lproj \ No newline at end of file diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..358d5e11617c3ac25ba9bd31a958601d261816dd Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..8cb4382ddd62810498119622d12b3ccf1a0ed3db Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..c7de27e606431d7d70929bf1832438c46dd301fa Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..68ae6e0ae7b71ed89581d779caaedd8a27c39f3e Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..d1f21da26c9c6d5a5e71ed65b91272b2757dd743 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..748e39cf661a1a4fa245e3c3a38bd7909ac864d0 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..2423538c9171ce8842f554e6f7fcd5fce3741951 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..99955afc5a20cc0ce4ba3e6415334bf307a5cf50 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..6cdc3d7a8c7b6f1c054fa0c8f488485c59ff325a Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..a3a92c80c4acca875bacb8445c5e8da8cb62dada Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..f7b43953b5e047ff1aa61e9ee2422485345d377f Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..faa546c86d66b947157270fe6bab01f99bbde633 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..fc4b0835003b82fb98d56660692ec38e20f30291 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..5ba7d96003075961749b68d5827a417f096c011b Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..6d570e8a6ea349f18c48964037a83361778cff3b Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..d5df79da54e5b1a0b5850553a86644c34a5a3fd2 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..5cca23d547be972f4235374ed602c36804201a16 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..3ba201625f768df920072dfe7535f397b9ef595e Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..5f5d1e84aa6bd225536fc05cb8e6b1f92add3c5e Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..05a426d15c2900c117e662f8d7828db5fdde0b88 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..546cc918f037700861a3f1540b531a4bfc1de661 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..3e13b051366ed95c050fca02d8da9288a51e8168 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..8e2e548d874c0364b3f05345a5cb52ac57a22ac3 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..95923ee0bb2689fc1a3808b5394e0b9ea840bbec Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..0bd403784257ab43281c77ba283d86053859f658 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..cc0943561b9501c1c499a2f69b79bdd6d541a6da Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..c8afe6d30f9f6fd9f29615d5c557b188290f3baf Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..d10801f5374464fd452424211f52104398815aaa Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt.lproj b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt.lproj new file mode 120000 index 0000000000000000000000000000000000000000..3c1c9f6dced30c7e4b955e9cef3ee89121cf4039 --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt.lproj @@ -0,0 +1 @@ +pt_BR.lproj \ No newline at end of file diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..1b5f6fca03615b64041713c442a753b559c25b86 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..f7c89b10682581875acfa996dced4eac30227604 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..0ce70b351c2f9db0142658393173afa68e56a31b Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..088cde6c2386511460fcf3235e39f340d4712636 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..bd666f7a489824747a4a53c5dc10a832b81bb6fd Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..ae56a6a938bf89e3523887b807ccc45a8c514d9c Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..9a85d7c00662755f9a285d9c0fd4a3df474d7d65 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..69853a3f0a90f5e617036231e4d5e808007ec080 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..88b32fbab3640fb5027223c9a2d0e6b94de5cbda Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..f43e74488866e9d954c76456f31bae657329f32e Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..461bed272882ea3fe6fe69ed69625491154117c9 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..3cd694d59dd3db13f47bfbe6088b7aba34852e58 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..e94b704cc26a8bde13b46fce02810c9d2e4724bc Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..97cf27df6664f958e78371322ba45419a8191661 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..f6d7e72be44fca63c8d23d1be52027d6d11dcff3 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..349f17fe3f5721bad05c7b7289fea17d4e52b0f8 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..194aaddcc549a76f690fffa0dc4b2c6e24290706 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..75f58b014ea16199e87ef8b5fbc80beaffbb39bc Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..e94310794d29eb036075536b036e085fc02fda19 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..38bb70dd077a32ecd7c70e465d06efb06b38ef84 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..6be828178ff6e39f56fdcb082c98c2cd26ccfc0c Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..e44ecfc390cc744be496f84887af3d171ff115a6 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..8beb43e905540d297b8ed775b63b3936a41e748c Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..889a6583e1f7ad676dfdebbb2ba680c97ddd2a70 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..7e45d9c96e048a974e41eb3b8fba9bf02b033113 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..0c65ace7ad08bbbb2666ef7c011e3713e77cc924 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..d702ceeb48dd4d22c96081591c05b051f8b424d0 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..e7e93079a70418c1d16bf1af6aaf208350d3dfa8 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..87c65eccde76b7a046260adfa273ddb9d2d8a776 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..416a939a075bb932cd761684cbdc226837d3669e Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..0276fc871fb4810b83b19a4bb7ba61c808f84bc5 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..323bb70feb0c74f4bf25201586984df03b1491e8 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..ce6d2c5435458fbdbd8c9328962163e5229fc76b Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..cbe48023c4fb06bd09aac499b0150a6b51df6eb1 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..8265ea9903c288a1db24f27728eb95cee526891a Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..74e17e44434dfae170ba9bcac2173c92cdaaf4d9 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..2c9a7015b0a3cc2b7bc91a676954a35884484ad3 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..855d4ad77459fc19f747a1444a52f43925131ca5 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..016c70cf9a123040cb81818a2e598a3af30495ff Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..bf13d969296e651f021a72bdd8e588952d9b209b Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..501e425d2f5dcf0c9df915d72686736a31608328 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..73a07091e7252975a0045d76a705dc285ec1dd21 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..13cb106377f79b72bcd06272c56661fd79e37e6d Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..49b68ce1e7b697bcefff97f7a62b6ca8365c74a9 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..24b24885716d495cd5977cf30d5eac7deaaec3dc Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib new file mode 100644 index 0000000000000000000000000000000000000000..c8bc317cbc49148002c40692d876db6afc58fde5 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib new file mode 100644 index 0000000000000000000000000000000000000000..e7f8dc9a003f0fa24edb6a570102e1956037c202 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings new file mode 100644 index 0000000000000000000000000000000000000000..d9229c96f1bc77843ea6d800e8f4a4f74e986078 Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Sparkle b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Sparkle new file mode 100755 index 0000000000000000000000000000000000000000..df9881628edff3be9186c88cc14ea57a43a32d1a Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Sparkle differ diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/Current b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/Current new file mode 120000 index 0000000000000000000000000000000000000000..8c7e5a667f1b771847fe88c01c3de34413a1b220 --- /dev/null +++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/bin/Metabase/Util.pm b/bin/Metabase/Util.pm new file mode 100644 index 0000000000000000000000000000000000000000..43b57849df7f2f072ed48c99055072c0a77bc294 --- /dev/null +++ b/bin/Metabase/Util.pm @@ -0,0 +1,77 @@ +use strict; +use warnings; + +package Metabase::Util; + +use Cwd 'getcwd'; +use Exporter; +use JSON; +use Term::ANSIColor qw(:constants); + +our @ISA = qw(Exporter); +our @EXPORT = qw(config + announce + print_giant_success_banner + get_file_or_die + plist_buddy_exec + OSX_ARTIFACTS_DIR + artifact); + +my $config_file = getcwd() . '/bin/config.json'; +die "Missing config file: $config_file\n" . + "Please copy $config_file.template, and edit it as needed before proceeding.\n" + unless (-e $config_file); +my $config = from_json(`cat $config_file`); + +sub config { + return $config->{ $_[0] }; +} + +sub announce { + print "\n\n" . GREEN . $_[0] . RESET . "\n\n"; +} + +sub print_giant_success_banner { + print "\n\n". BLUE . + '+----------------------------------------------------------------------+' . "\n" . + '| |' . "\n" . + '| _______ _______ _______ _______ _______ _______ _ |' . "\n" . + '| ( ____ \|\ /|( ____ \( ____ \( ____ \( ____ \( ____ \( ) |' . "\n" . + '| | ( \/| ) ( || ( \/| ( \/| ( \/| ( \/| ( \/| | |' . "\n" . + '| | (_____ | | | || | | | | (__ | (_____ | (_____ | | |' . "\n" . + '| (_____ )| | | || | | | | __) (_____ )(_____ )| | |' . "\n" . + '| ) || | | || | | | | ( ) | ) |(_) |' . "\n" . + '| /\____) || (___) || (____/\| (____/\| (____/\/\____) |/\____) | _ |' . "\n" . + '| \_______)(_______)(_______/(_______/(_______/\_______)\_______)(_) |' . "\n" . + '| |' . "\n" . + '| |' . "\n" . + '+----------------------------------------------------------------------+' . RESET . "\n\n"; +} + +# Check if a file exists, or die. +# If file path is relative, qualify it by prepending the current dir. +# Return the fully-qualified file path. +sub get_file_or_die { + my ($filename) = @_; + $filename = (getcwd() . '/' . $filename) if $filename !~ /^\//; + + die "Error: $filename does not exist.\n" unless -e $filename; + + return $filename; +} + +# Run a PlistBuddy command against Metabase-Info.plist +sub plist_buddy_exec { + my $info_plist = get_file_or_die('OSX/Metabase/Metabase-Info.plist'); + return `/usr/libexec/PlistBuddy -c '@_' "$info_plist"`; +} + +use constant OSX_ARTIFACTS_DIR => getcwd() . '/osx-artifacts'; +sub artifact { + # Make the artifacts directory if needed + system('mkdir', OSX_ARTIFACTS_DIR) if ! -d OSX_ARTIFACTS_DIR; + + return OSX_ARTIFACTS_DIR . "/$_[0]"; +} + +1; diff --git a/bin/config.json.template b/bin/config.json.template new file mode 100644 index 0000000000000000000000000000000000000000..4339e9c78d583f34b16221c859644d73216ef330 --- /dev/null +++ b/bin/config.json.template @@ -0,0 +1,7 @@ +{ + "codesigningIdentity": "Developer ID Application: Metabase, Inc", + "slackWebhookURL": "", + "awsProfile": "metabase", + "awsRegion": "", + "awsBucket": "" +} diff --git a/bin/lib/sign_update.rb b/bin/lib/sign_update.rb new file mode 100755 index 0000000000000000000000000000000000000000..6d03e2ef0c26802d0a55b6450d0391130c4448d6 --- /dev/null +++ b/bin/lib/sign_update.rb @@ -0,0 +1,7 @@ +#!/usr/bin/ruby +if ARGV.length < 2 + puts "Usage: ruby sign_update.rb update_archive private_key" + exit +end + +puts `openssl dgst -sha1 -binary < "#{ARGV[0]}" | openssl dgst -dss1 -sign "#{ARGV[1]}" | openssl enc -base64` \ No newline at end of file diff --git a/bin/osx-release b/bin/osx-release new file mode 100755 index 0000000000000000000000000000000000000000..e2a067ce1d216eb2634035715fb09d5bf4cf6b35 --- /dev/null +++ b/bin/osx-release @@ -0,0 +1,366 @@ +#! /usr/bin/perl -I./bin + +use strict; +use warnings; + +use Cwd 'getcwd'; +use File::Copy 'copy'; +use File::Copy::Recursive 'rcopy'; # CPAN +use File::Path 'remove_tree'; +use File::stat 'stat'; +use JSON 'encode_json', 'from_json'; # CPAN +use Readonly; # CPAN +use String::Util 'trim'; # CPAN +use WWW::Curl::Simple; # CPAN + +use Metabase::Util; + +Readonly my $app => artifact('Metabase.app'); +Readonly my $zipfile => artifact('Metabase.zip'); +Readonly my $appcast => artifact('appcast.xml'); +Readonly my $release_notes => artifact('release-notes.html'); +Readonly my $dmg => artifact('Metabase.dmg'); +Readonly my @files_to_upload => ($zipfile, $appcast, $release_notes, $dmg); + +Readonly my $xcode_project => get_file_or_die('OSX/Metabase.xcodeproj'); + +# Get the version saved in the CFBundle, e.g. 0.11.3.1 +sub version { + return trim(plist_buddy_exec('Print', 'CFBundleVersion')); +} + +# Next version after version(), e.g. 0.11.3.2 +sub next_version { + my ($old_version_tag, $old_version_point_release) = (version() =~ /^(\d+\.\d+\.\d+)\.(\d+)$/); + + # Get the tag saved in version.properties + my $tag_from_props_file = ''; + open(FILE, get_file_or_die('resources/version.properties')) or die $!; + while (<FILE>) { m/^tag/ && s/^tag=v(.+)$/$1/ && ($tag_from_props_file = trim($_)); }; + + # Now calculate the new version, which is ($tag.$point_release) + # Check and see if tag has changed in version.properties; if so, new version is the first "point release" of that tag. + return $old_version_tag eq $tag_from_props_file ? ($old_version_tag . '.' . ($old_version_point_release + 1)) : "$tag_from_props_file.0"; +} + +sub bump_version { + Readonly my $new_version => next_version(); + announce 'Bumping version: ' . version() . " -> $new_version"; + + plist_buddy_exec('Set', ':CFBundleVersion', $new_version); + plist_buddy_exec('Set', ':CFBundleShortVersionString', $new_version); +} + +sub clean { + system('xcodebuild', 'clean', '-project', $xcode_project) == 0 or die $!; + remove_tree(OSX_ARTIFACTS_DIR); +} + +# Build Metabase.app +sub build { + announce "Building $app..."; + + Readonly my $xcarchive => artifact('Metabase.xcarchive'); + + # remove old artifacts if they exist + remove_tree($xcarchive, $app); + + # Build the project and generate Metabase.xcarchive + system('xcodebuild', + '-project', $xcode_project, + '-scheme', 'Metabase', + '-configuration', 'Release', + '-archivePath', $xcarchive, + 'archive') == 0 or die $!; + + # Ok, now create the Metabase.app artifact + system('xcodebuild', + '-exportArchive', + '-exportFormat', 'APP', + '-archivePath', $xcarchive, + '-exportPath', $app) == 0 or die $!; + + # Ok, we can remove the .xcarchive file now + remove_tree($xcarchive); +} + +# Codesign Metabase.app +sub codesign { + my $codesigning_cert_name = config('codesigningIdentity') or return; + + announce "Codesigning $app..."; + + system('codesign', '--force', '--verify', + '--sign', $codesigning_cert_name, + '-r=designated => anchor trusted', + '--deep', get_file_or_die($app)) == 0 or die "Code signing failed: $!\n"; +} + +# Verify that Metabase.app was signed correctly +sub verify_codesign { + return unless config('codesigningIdentity'); + + announce "Verifying codesigning for $app..."; + + system('codesign', '--verify', '--deep', '--display', + '--verbose=4', get_file_or_die($app)) == 0 or die "Code signing verification failed: $!\n"; + + # Double-check with System Policy Security tool + system('spctl', '--assess', '--verbose=4', get_file_or_die($app)) == 0 +} + + +# ------------------------------------------------------------ PACKAGING FOR SPARKLE ------------------------------------------------------------ + +# Create ZIP containing Metabase.app +sub archive { + announce "Creating $zipfile..."; + + remove_tree($zipfile); + + get_file_or_die($app); + + system('cd ' . OSX_ARTIFACTS_DIR . ' && zip -r Metabase.zip Metabase.app') == 0 or die $!; + get_file_or_die($zipfile); +} + +sub generate_signature { + Readonly my $private_key_file => getcwd() . '/OSX/dsa_priv.pem'; + + unless (-e $private_key_file) { + warn "Missing private key file: $private_key_file\n"; + return; + } + + Readonly my $sign_update_script => get_file_or_die('bin/lib/sign_update.rb'); + + get_file_or_die($zipfile); + + return trim(`$sign_update_script "$zipfile" "$private_key_file"`); +} + +# Generate the appcast.xml RSS feed file that Sparkle reads to check for updates +sub generate_appcast { + announce "Generating $appcast..."; + + remove_tree($appcast); + + my $aws_region = config('awsRegion') or return; + my $aws_bucket = config('awsBucket') or return; + my $signature = generate_signature() or return; + + Readonly my $appcast_template => get_file_or_die('bin/templates/appcast.xml.template'); + Readonly my $filesize => stat(get_file_or_die($zipfile))->size; + Readonly my $version => version(); + + open(my $in, '<', $appcast_template) or die "Unable to read $appcast_template: $!"; + open(my $out, '>', $appcast) or die "Unable to write to $appcast: $!"; + + print "SIGNATURE: '$signature'\n"; + + while ( <$in> ) { + s/{{VERSION}}/$version/; + s/{{SIGNATURE}}/$signature/; + s/{{LENGTH}}/$filesize/; + s/{{S3_REGION}}/$aws_region/; + s/{{S3_BUCKET}}/$aws_bucket/; + print $out $_; + } + + close $out; +} + +sub edit_release_notes { + remove_tree($release_notes); + + copy(get_file_or_die('bin/templates/release-notes.html.template'), $release_notes) or die $!; + system('emacs', get_file_or_die($release_notes)) == 0 or die $!; +} + + +# ------------------------------------------------------------ CREATING DMG ------------------------------------------------------------ + +sub create_dmg_from_source_dir { + my ($source_dir, $dmg_filename) = @_; + announce "Creating DMG: $dmg_filename from source $source_dir..."; + + system('hdiutil', 'create', + '-srcfolder', $source_dir, + '-volname', 'Metabase', + '-fs', 'HFS+', + '-fsargs', '-c c=64,a=16,e=16', + '-format', 'UDRW', + '-size', '144MB', # it looks like this can be whatever size we want; compression slims it down + $dmg_filename) == 0 or die $!; +} + +# Mount the disk image, return the device name +sub mount_dmg { + my ($dmg_filename) = @_; + announce "Mounting DMG..."; + + my $device = `hdiutil attach -readwrite -noverify -noautoopen $dmg_filename`; + # Find the device name: the part of the output looks like /dev/disk11 + for my $token (split(/\s+/, $device)) { + if ($token =~ m|^/dev/|) { + $device = $token; + last; + } + } + + announce "Mounted $dmg_filename at $device"; + return $device; +} + +sub dmg_add_applications_shortcut { + announce "Adding shortcut to /Applications..."; + + system('osascript', '-e', + 'tell application "Finder" + tell disk "Metabase" + open + set current view of container window to icon view + set toolbar visible of container window to false + set statusbar visible of container window to false + set the bounds of container window to {400, 100, 885, 430} + set theViewOptions to the icon view options of container window + set arrangement of theViewOptions to not arranged + set icon size of theViewOptions to 72 + make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"} + set position of item "Metabase.app" of container window to {100, 100} + set position of item "Applications" of container window to {375, 100} + update without registering applications + delay 5 + close + end tell + end tell') == 0 or die $!; +} + +sub finalize_dmg { + my ($device, $dmg_filename) = @_; + announce "Finalizing DMG..."; + + # Remove any hidden files that creeped into the DMG + remove_tree('/Volumes/Metabase/.Trashes', + '/Volumes/Metabase/.fseventsd'); + + + # Set DMG permissions, force completion of pending disk writes + system('chmod', '-Rf', 'go-w', '/Volumes/Metabase') == 0 or warn $!; # this might issue warnings about not being able to affect .Trashes + system('sync'); + system('sync'); + + # unmount the temp DMG + announce "Unmounting $device..."; + system('hdiutil', 'detach', $device) == 0 or die $!; + + # compress the DMG + announce "Compressing DMG..."; + system('hdiutil', 'convert', $dmg_filename, + '-format', 'UDZO', + '-imagekey', 'zlib-level-9', + '-o', $dmg) == 0 or die $!; +} + +sub create_dmg { + announce "Preparing DMG files..."; + + # detach any existing Metabase DMGs + system('hdiutil', 'detach', '/Volumes/Metabase') if -d '/Volumes/Metabase'; + + Readonly my $temp_dmg => artifact('Metabase.temp.dmg'); + Readonly my $dmg_source_dir => artifact('dmg'); + + # Clean up old artifacts + remove_tree($dmg_source_dir, $temp_dmg, $dmg); + mkdir $dmg_source_dir or die $!; + + # Copy Metabase.app into the source dir + rcopy(get_file_or_die($app), $dmg_source_dir . '/Metabase.app') or die $!; + + # Ok, now proceed with the steps to create the DMG + create_dmg_from_source_dir($dmg_source_dir, $temp_dmg); + + Readonly my $device => mount_dmg($temp_dmg); + + dmg_add_applications_shortcut; + + finalize_dmg($device, $temp_dmg); + + announce "DMG created successfully: $dmg"; + + # Cleanup: remove temp file & temp dir + remove_tree($temp_dmg, $dmg_source_dir); +} + + +# ------------------------------------------------------------ UPLOADING ------------------------------------------------------------ + +sub announce_on_slack { + Readonly my $slack_url => config('slackWebhookURL') or return; + Readonly my $version => version(); + Readonly my $awsURL => 'https://s3-' . config('awsRegion') . 'amazonaws.com/' . config('awsBucket') . '/Metabase.dmg'; + my $text = "Metabase OS X $version 'Turbulent Toucan' Is Now Available!\n\n" . + "Get it here: $awsURL\n\n"; + + open(my $file, get_file_or_die($release_notes)) or die $!; + while (<$file>) { + m/^\s+<li>.*$/ && s|^\s+<li>(.*)</li>$|$1| && ($text .= '* ' . $_); + } + + my $json = encode_json { + channel => '#general', + username => 'OS X Bot', + icon_emoji => ':bird:', + text => trim($text) + }; + + my $curl = WWW::Curl::Simple->new; + unless ((my $response = $curl->post($slack_url, $json))->code == 200) { + die 'Error posting to slack: ' . $response->code . ' ' . $response->content . "\n"; + } +} + +# Upload artifacts to AWS +# Make sure to run `aws configure --profile metabase` first to set up your ~/.aws/config file correctly +sub upload { + my $aws_profile = config('awsProfile') or return; + my $aws_region = config('awsRegion') or return; + my $aws_bucket = config('awsBucket') or return; + + for my $file (@files_to_upload) { + announce "Uploading $file ..."; + system('aws', + '--profile', $aws_profile, + '--region', $aws_region, + 's3', 'cp', get_file_or_die($file), + "s3://$aws_bucket") == 0 or die "Upload failed: $!\n"; + } + + announce_on_slack; + + announce "Upload finished." +} + + +# ------------------------------------------------------------ RUN ALL ------------------------------------------------------------ + +sub all { + clean; + bump_version; + build; + codesign; + verify_codesign; + archive; + generate_appcast; + edit_release_notes; + create_dmg; + upload; +} + +# Run all the commands specified in command line args, otherwise default to running 'all' +@ARGV = ('all') unless @ARGV; +no strict 'refs'; +map { $_->(); } @ARGV; + +print_giant_success_banner(); diff --git a/bin/osx-setup b/bin/osx-setup new file mode 100755 index 0000000000000000000000000000000000000000..65c7085759ad41a460945d044657666835aae13b --- /dev/null +++ b/bin/osx-setup @@ -0,0 +1,85 @@ +#! /usr/bin/perl -I./bin + +use strict; +use warnings; + +use Cwd 'getcwd'; +use File::Copy 'copy'; +use File::Copy::Recursive 'rcopy'; +use File::Find 'find'; +use File::Path 'remove_tree'; +use String::Util 'trim'; + +use Metabase::Util; + +use constant JRE_DEST => getcwd() . '/OSX/Metabase/jre'; +use constant JRE_HOME => trim(`/usr/libexec/java_home`) . '/jre'; + +use constant UBERJAR_SRC => getcwd() . '/target/uberjar/metabase-standalone.jar'; +use constant UBERJAR_DEST => getcwd() . '/OSX/Resources/metabase.jar'; + +use constant ENABLE_JAR_PACKING => 0; + +sub remove_jre_optional_files { + my @optional_files = ('bin/keytool', + 'bin/orbd', + 'bin/policytool', + 'bin/rmid', + 'bin/rmiregistry', + 'bin/servertool', + 'bin/tnameserv', + 'lib/cmm/PYCC.pf', + 'lib/deploy.jar', + 'lib/ext', + 'lib/fonts', + 'lib/javaws.jar', + 'lib/jfr', + 'lib/jfr.jar', + 'lib/libglass.dylib', + 'lib/libglib-lite.dylib', + 'lib/libgstreamer-lite.dylib', + 'lib/libjavafx_font_t2k.dylib', + 'lib/libjfxmedia.dylib', + 'lib/libjfxwebkit.dylib', + 'lib/libprism_common.dylib', + 'lib/libprism_sw.dylib', + 'lib/plugin.jar', + 'lib/javafx.properties', + 'lib/jfxswt.jar' + ); + for my $file (@optional_files) { + $file = JRE_DEST . '/' . $file; + remove_tree($file) if -e $file; + } +} + +# Finds all the .jar files in JRE_DEST and replaces them with packed .pack.gz files. +sub pack_jre_jars { + sub pack_jar { + if (/\.jar$/) { + s/(^.*)\.jar$/$1/; # stip off extension + print "Packing $_.jar...\n"; + system('pack200', '--gzip', '--strip-debug', '--effort=9', $_ . '.pack.gz', $_ . '.jar') == 0 or die $!; + remove_tree($_ . '.jar'); + } + } + find(\&pack_jar, JRE_DEST . '/lib'); +} + +# Copy the JRE if needed +(rcopy(JRE_HOME, JRE_DEST) or die $!) unless -d JRE_DEST; + +# Remove optional files from JRE dest +remove_jre_optional_files(); + +# Pack JARs in JRE if applicable +pack_jar() if ENABLE_JAR_PACKING; + +# Build uberjar if needed +(system('./bin/build') or die $!) unless -f UBERJAR_SRC; + +# Copy uberjar over +announce 'Copying uberjar ' . UBERJAR_SRC . ' -> ' . UBERJAR_DEST; +copy(get_file_or_die(UBERJAR_SRC), UBERJAR_DEST) or die $!; + +print_giant_success_banner(); diff --git a/bin/templates/appcast.xml.template b/bin/templates/appcast.xml.template new file mode 100644 index 0000000000000000000000000000000000000000..5c60cb7e38cbee98b8b8ee562d3eb0e22d03e2a3 --- /dev/null +++ b/bin/templates/appcast.xml.template @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/"> + <channel> + <title> + Metabase Changelog + </title> + <link> + https://{{S3_REGION}}.amazonaws.com/{{S3_BUCKET}}/appcast.xml + </link> + <language> + en + </language> + <item> + <title> + Version {{VERSION}} + </title> + <sparkle:releaseNotesLink> + https://{{S3_REGION}}.amazonaws.com/{{S3_BUCKET}}/release-notes.html + </sparkle:releaseNotesLink> + <enclosure url="https://{{S3_REGION}}.amazonaws.com/{{S3_BUCKET}}/Metabase.zip" + sparkle:version="{{VERSION}}" + length="{{LENGTH}}" + type="application/octet-stream" + sparkle:dsaSignature="{{SIGNATURE}}" /> + </item> + </channel> +</rss> diff --git a/bin/templates/release-notes.html.template b/bin/templates/release-notes.html.template new file mode 100644 index 0000000000000000000000000000000000000000..d8360f1278798b8312e4bf01f73b7f425a00d8de --- /dev/null +++ b/bin/templates/release-notes.html.template @@ -0,0 +1,10 @@ +<html> + <head> + <title>Metabase Release Notes</title> + </head> + <body> + <ul> + <li>What's changed in this update? Put notes here.</li> + </ul> + </body> +</html> diff --git a/docs/developers-guide-osx.md b/docs/developers-guide-osx.md new file mode 100644 index 0000000000000000000000000000000000000000..64f911477f2b40214482de6dff324ee3fdfd0852 --- /dev/null +++ b/docs/developers-guide-osx.md @@ -0,0 +1,46 @@ +# Metabase OS X App + +## Prereqs + +You'll need to run the following commands before building the app: + +```bash +# Fetch and initialize git submodule +git submodule update --init + +# Install Perl modules used by ./setup and ./release +sudo cpan install File::Copy::Recursive JSON Readonly String::Util WWW::Curl::Simple + +# Copy JRE and uberjar +./bin/osx-setup +``` + +`./bin/osx-setup` will build run commands to build the uberjar for you if needed. +Run `./bin/osx-setup` again at any time in the future to copy the latest version of the uberjar into the project. + + +## Releasing + +A handy Perl script called `./bin/osx-release` takes care of all of the details for you. Before you run it for the first time, you'll need to set up a few additional things: + +```bash +# Configure AWS Credentials +# You'll need credentials that give you permission to write the metabase-osx-releases S3 bucket. +aws configure --profile metabase + +# Copy & Edit Config file +cp bin/config.json.template bin/config.json +emacs bin/config.json + +# Obtain a copy of the private key used for signing the app (ask Cam) +# and put a copy of it at ./dsa_priv.pem +cp /path/to/private/key.pem OSX/dsa_priv.pem +``` + +You'll probably also want an Apple Developer ID Application Certificate in your computer's keychain (ask Cam). + +After that, you are good to go: +```bash +# Bundle entire app, and upload to s3 +./release +``` diff --git a/docs/developers-guide.md b/docs/developers-guide.md index 40a8a3ebbc693c1e8d053708a7cf0aea66f06dba..3a55ee0e26b830855c76214629f1ca610943bb32 100644 --- a/docs/developers-guide.md +++ b/docs/developers-guide.md @@ -1,9 +1,9 @@ -> **This guide will teach you:** -> How to compile your own copy of Metabase -> How to set up a development environment -> How to run the Metabase Server -> How to contribute back to the Metabase project +> **This guide will teach you:** +> How to compile your own copy of Metabase +> How to set up a development environment +> How to run the Metabase Server +> How to contribute back to the Metabase project [](https://circleci.com/gh/metabase/metabase-init) @@ -25,6 +25,10 @@ The entire Metabase application is compiled and assembled into a single .jar fil After running the build script simply look in `target/uberjar` for the output .jar file and you are ready to go. +## Building the OS X App + +See [this guide](developers-guide-osx.md). + # Development Environment @@ -120,7 +124,7 @@ Run unit tests with or a specific test with - lein test metabase.api.session-test + lein test metabase.api.session-test By default, the tests only run against the `h2` dataset (built-in test database). You can specify which datasets/drivers to run tests against with the env var `MB_TEST_DATASETS`: