From a71953283798d9b3f0bad4d08384053d3ca88b24 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 7 May 2018 13:36:06 -0700 Subject: [PATCH] Initial release. --- .gitignore | 71 +++ Documentation/Enums.html | 122 ++++ Documentation/Enums/KeychainError.html | 166 +++++ Documentation/Protocols.html | 122 ++++ Documentation/Protocols/KeychainItem.html | 478 ++++++++++++++ Documentation/Structs.html | 122 ++++ Documentation/Structs/Keychain.html | 599 +++++++++++++++++ Documentation/Structs/Keychain/Access.html | 190 ++++++ .../Structs/Keychain/Configuration.html | 229 +++++++ Documentation/Structs/Keychain/Storage.html | 159 +++++ Documentation/Typealiases.html | 121 ++++ Documentation/badge.svg | 28 + Documentation/css/highlight.css | 200 ++++++ Documentation/css/jazzy.css | 337 ++++++++++ Documentation/docs.sh | 8 + .../Keychain.docset/Contents/Info.plist | 20 + .../Contents/Resources/Documents/Enums.html | 122 ++++ .../Documents/Enums/KeychainError.html | 166 +++++ .../Resources/Documents/Protocols.html | 122 ++++ .../Documents/Protocols/KeychainItem.html | 478 ++++++++++++++ .../Contents/Resources/Documents/Structs.html | 122 ++++ .../Resources/Documents/Structs/Keychain.html | 599 +++++++++++++++++ .../Documents/Structs/Keychain/Access.html | 190 ++++++ .../Structs/Keychain/Configuration.html | 229 +++++++ .../Documents/Structs/Keychain/Storage.html | 159 +++++ .../Resources/Documents/Typealiases.html | 121 ++++ .../Contents/Resources/Documents/badge.svg | 28 + .../Resources/Documents/css/highlight.css | 200 ++++++ .../Resources/Documents/css/jazzy.css | 337 ++++++++++ .../Resources/Documents/img/carat.png | Bin 0 -> 274 bytes .../Contents/Resources/Documents/img/dash.png | Bin 0 -> 1338 bytes .../Contents/Resources/Documents/img/gh.png | Bin 0 -> 1571 bytes .../Contents/Resources/Documents/index.html | 188 ++++++ .../Contents/Resources/Documents/js/jazzy.js | 46 ++ .../Resources/Documents/js/jquery.min.js | 4 + .../Contents/Resources/Documents/search.json | 1 + .../Resources/Documents/undocumented.json | 6 + .../Contents/Resources/docSet.dsidx | Bin 0 -> 12288 bytes Documentation/docsets/Keychain.tgz | Bin 0 -> 51504 bytes Documentation/img/carat.png | Bin 0 -> 274 bytes Documentation/img/dash.png | Bin 0 -> 1338 bytes Documentation/img/gh.png | Bin 0 -> 1571 bytes Documentation/index.html | 188 ++++++ Documentation/js/jazzy.js | 46 ++ Documentation/js/jquery.min.js | 4 + Documentation/search.json | 1 + Documentation/undocumented.json | 6 + .../Example/Example.xcodeproj/project.pbxproj | 602 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/xcschemes/Example.xcscheme | 101 +++ Example/Example/Example/AppDelegate.swift | 22 + .../Controllers/ItemsViewController.swift | 51 ++ .../Controllers/NewItemViewController.swift | 56 ++ ...ViewController+UITableViewDataSource.swift | 35 + ...msViewController+UITableViewDelegate.swift | 56 ++ .../Example/Example/Global/Constants.swift | 22 + Example/Example/Example/Info.plist | 43 ++ Example/Example/Example/Models/Item.swift | 39 ++ .../AppIcon.appiconset/Contents.json | 98 +++ .../Views/Base.lproj/LaunchScreen.storyboard | 25 + Example/Example/Example/Views/Main.storyboard | 157 +++++ Example/Example/KeychainTests/Info.plist | 22 + .../Keychain/KeychainBaseCase.swift | 61 ++ .../Keychain/KeychainConfigurationTests.swift | 33 + .../Keychain/KeychainDeleteTests.swift | 81 +++ .../Keychain/KeychainItemTests.swift | 41 ++ .../Keychain/KeychainSaveTests.swift | 103 +++ .../Keychain/KeychainSearchTests.swift | 89 +++ .../Example/KeychainTests/Models/Card.swift | 32 + .../Example/KeychainTests/Models/User.swift | 33 + Framework/Keychain.xcodeproj/project.pbxproj | 482 ++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/xcschemes/Keychain.xcscheme | 89 +++ .../Common/Errors/KeychainError.swift | 31 + .../Common/Protocols/Types/KeychainItem.swift | 76 +++ .../Foundation/CFString+Additions.swift | 24 + .../Foundation/Data+Additions.swift | 24 + .../Foundation/Dictionary+Additions.swift | 24 + .../Foundation/String+Additions.swift | 24 + .../Framework/Keychain/Keychain+Access.swift | 43 ++ .../Keychain/Keychain+Configuration.swift | 48 ++ .../Framework/Keychain/Keychain+Manager.swift | 105 +++ .../Framework/Keychain/Keychain+Storage.swift | 37 ++ .../KeychainItem+Implementation.swift | 63 ++ .../KeychainItem/KeychainItem+Query.swift | 65 ++ Framework/Keychain/Global/Definitions.swift | 20 + Framework/Keychain/Info.plist | 24 + Framework/Keychain/Keychain.h | 27 + Framework/Keychain/Keychain/Keychain.swift | 133 ++++ Keychain.xcworkspace/contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + LICENSE | 15 + README.md | 102 +++ 93 files changed, 9625 insertions(+) create mode 100644 .gitignore create mode 100644 Documentation/Enums.html create mode 100644 Documentation/Enums/KeychainError.html create mode 100644 Documentation/Protocols.html create mode 100644 Documentation/Protocols/KeychainItem.html create mode 100644 Documentation/Structs.html create mode 100644 Documentation/Structs/Keychain.html create mode 100644 Documentation/Structs/Keychain/Access.html create mode 100644 Documentation/Structs/Keychain/Configuration.html create mode 100644 Documentation/Structs/Keychain/Storage.html create mode 100644 Documentation/Typealiases.html create mode 100644 Documentation/badge.svg create mode 100644 Documentation/css/highlight.css create mode 100644 Documentation/css/jazzy.css create mode 100755 Documentation/docs.sh create mode 100644 Documentation/docsets/Keychain.docset/Contents/Info.plist create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Enums.html create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Enums/KeychainError.html create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Protocols.html create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Protocols/KeychainItem.html create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs.html create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain.html create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain/Access.html create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain/Configuration.html create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain/Storage.html create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Typealiases.html create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/badge.svg create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/css/highlight.css create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/css/jazzy.css create mode 100755 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/img/carat.png create mode 100755 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/img/dash.png create mode 100755 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/img/gh.png create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/index.html create mode 100755 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/js/jazzy.js create mode 100755 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/js/jquery.min.js create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/search.json create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/Documents/undocumented.json create mode 100644 Documentation/docsets/Keychain.docset/Contents/Resources/docSet.dsidx create mode 100644 Documentation/docsets/Keychain.tgz create mode 100755 Documentation/img/carat.png create mode 100755 Documentation/img/dash.png create mode 100755 Documentation/img/gh.png create mode 100644 Documentation/index.html create mode 100755 Documentation/js/jazzy.js create mode 100755 Documentation/js/jquery.min.js create mode 100644 Documentation/search.json create mode 100644 Documentation/undocumented.json create mode 100644 Example/Example/Example.xcodeproj/project.pbxproj create mode 100644 Example/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 Example/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme create mode 100644 Example/Example/Example/AppDelegate.swift create mode 100644 Example/Example/Example/Controllers/ItemsViewController.swift create mode 100644 Example/Example/Example/Controllers/NewItemViewController.swift create mode 100644 Example/Example/Example/Extensions/Application/Controllers/ItemsViewController+UITableViewDataSource.swift create mode 100644 Example/Example/Example/Extensions/Application/Controllers/ItemsViewController+UITableViewDelegate.swift create mode 100644 Example/Example/Example/Global/Constants.swift create mode 100644 Example/Example/Example/Info.plist create mode 100644 Example/Example/Example/Models/Item.swift create mode 100644 Example/Example/Example/Views/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Example/Example/Example/Views/Base.lproj/LaunchScreen.storyboard create mode 100644 Example/Example/Example/Views/Main.storyboard create mode 100644 Example/Example/KeychainTests/Info.plist create mode 100644 Example/Example/KeychainTests/Keychain/KeychainBaseCase.swift create mode 100644 Example/Example/KeychainTests/Keychain/KeychainConfigurationTests.swift create mode 100644 Example/Example/KeychainTests/Keychain/KeychainDeleteTests.swift create mode 100644 Example/Example/KeychainTests/Keychain/KeychainItemTests.swift create mode 100644 Example/Example/KeychainTests/Keychain/KeychainSaveTests.swift create mode 100644 Example/Example/KeychainTests/Keychain/KeychainSearchTests.swift create mode 100644 Example/Example/KeychainTests/Models/Card.swift create mode 100644 Example/Example/KeychainTests/Models/User.swift create mode 100644 Framework/Keychain.xcodeproj/project.pbxproj create mode 100644 Framework/Keychain.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 Framework/Keychain.xcodeproj/xcshareddata/xcschemes/Keychain.xcscheme create mode 100644 Framework/Keychain/Common/Errors/KeychainError.swift create mode 100644 Framework/Keychain/Common/Protocols/Types/KeychainItem.swift create mode 100644 Framework/Keychain/Extensions/Foundation/CFString+Additions.swift create mode 100644 Framework/Keychain/Extensions/Foundation/Data+Additions.swift create mode 100644 Framework/Keychain/Extensions/Foundation/Dictionary+Additions.swift create mode 100644 Framework/Keychain/Extensions/Foundation/String+Additions.swift create mode 100644 Framework/Keychain/Extensions/Framework/Keychain/Keychain+Access.swift create mode 100644 Framework/Keychain/Extensions/Framework/Keychain/Keychain+Configuration.swift create mode 100644 Framework/Keychain/Extensions/Framework/Keychain/Keychain+Manager.swift create mode 100644 Framework/Keychain/Extensions/Framework/Keychain/Keychain+Storage.swift create mode 100644 Framework/Keychain/Extensions/Framework/KeychainItem/KeychainItem+Implementation.swift create mode 100644 Framework/Keychain/Extensions/Framework/KeychainItem/KeychainItem+Query.swift create mode 100644 Framework/Keychain/Global/Definitions.swift create mode 100644 Framework/Keychain/Info.plist create mode 100644 Framework/Keychain/Keychain.h create mode 100644 Framework/Keychain/Keychain/Keychain.swift create mode 100644 Keychain.xcworkspace/contents.xcworkspacedata create mode 100644 Keychain.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 LICENSE create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a62418d --- /dev/null +++ b/.gitignore @@ -0,0 +1,71 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +/.DS_Store +.DS_Store +/Framework/docs diff --git a/Documentation/Enums.html b/Documentation/Enums.html new file mode 100644 index 0000000..4a589bd --- /dev/null +++ b/Documentation/Enums.html @@ -0,0 +1,122 @@ + + + + Enumerations Reference + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Enumerations

+

The following enumerations are available globally.

+ +
+
+
+
    +
  • +
    + + + + KeychainError + +
    +
    +
    +
    +
    +
    +

    List of possible error cases thrown by Keychain operations.

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public enum KeychainError: Error
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/Enums/KeychainError.html b/Documentation/Enums/KeychainError.html new file mode 100644 index 0000000..db35e9d --- /dev/null +++ b/Documentation/Enums/KeychainError.html @@ -0,0 +1,166 @@ + + + + KeychainError Enumeration Reference + + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

KeychainError

+
+
+
public enum KeychainError: Error
+ +
+
+

List of possible error cases thrown by Keychain operations.

+ +
+
+
+
    +
  • +
    + + + + unexpectedItemData + +
    +
    +
    +
    +
    +
    +

    Keychain search returned unexpected item data.

    +
    +

    Note

    + Only thrown when retrieving items from the Keychain fails due to SecItemCopyMatching query returning anything but an array of [String: AnyObject]. + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    case unexpectedItemData
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + unhandled + +
    +
    +
    +
    +
    +
    +

    Unhandled error returned by Keychain operation.

    + +

    For list of OSStatus codes, please see https://www.osstatus.com/

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    case unhandled(OSStatus)
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/Protocols.html b/Documentation/Protocols.html new file mode 100644 index 0000000..d795af8 --- /dev/null +++ b/Documentation/Protocols.html @@ -0,0 +1,122 @@ + + + + Protocols Reference + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Protocols

+

The following protocols are available globally.

+ +
+
+
+
    +
  • +
    + + + + KeychainItem + +
    +
    +
    +
    +
    +
    +

    A type that can represent conforming model as a KeychainItem.

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public protocol KeychainItem: Codable
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/Protocols/KeychainItem.html b/Documentation/Protocols/KeychainItem.html new file mode 100644 index 0000000..99aa05b --- /dev/null +++ b/Documentation/Protocols/KeychainItem.html @@ -0,0 +1,478 @@ + + + + KeychainItem Protocol Reference + + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

KeychainItem

+
+
+
public protocol KeychainItem: Codable
+ +
+
+

A type that can represent conforming model as a KeychainItem.

+ +
+
+
+
    +
  • +
    + + + + comment + + + Default implementation + +
    +
    +
    +
    +
    +
    +

    The instance comment saved as an attribute on a Keychain item using kSecAttrComment key.

    + +
    +

    Default Implementation

    +
    +
    +

    Note

    + The default valus is nil. + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    var comment: String?
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + description + + + Default implementation + +
    +
    +
    +
    +
    +
    +

    The instance description saved as an attribute on a Keychain item using kSecAttrDescription key.

    + +
    +

    Default Implementation

    +
    +
    +

    Note

    + The default valus is nil. + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    var description: String?
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + idKey + +
    +
    +
    +
    +
    +
    +

    The instance identifier saved as an attribute on a Keychain item using kSecAttrAccount key.

    +
    +

    Warning

    +

    If you intend to store multiple instances of the same type, idKey must be unique to each instance. +Failing to do so will result in having previously saved instance maching this idKey overriden.

    + +
    +
  • Consider this implementation:

    +
    struct User: KeychainItem {
    +  let email: String
    +
    +  // MARK: KeychainItem
    +
    +  var idKey: String {
    +      return email
    +  }
    +}
    +
    + +

    In the above example, the idKey is set to be the email address of the user. +You can use the idKey later to perform a search like this:

  • +
      try keychain.item(ofType: User.self, idKey: "email@alaskaair.com")
    +
    + +

    If only a single instance of a type will be stored, the idKey can be set using typeKey.

    +
      struct SSOCredential: KeychainItem {
    +      let accessToken: String
    +
    +      // MARK: KeychainItem
    +
    +      var idKey: String {
    +          return SSOCredential.typeKey
    +      }
    +  }
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    var idKey: String
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + storage + + + Default implementation + +
    +
    +
    +
    +
    +
    +

    The storage option of the item for specifying Keychain storage type using kSecClass key.

    + +
    +

    Default Implementation

    +
    +
    +

    Note

    + The default value is .genericPassword. + +
    + +

    This Keychain framework only supports kSecClassGenericPassword for now.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    static var storage: Keychain.Storage
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + typeKey + + + Default implementation + +
    +
    +
    +
    +
    +
    +

    The type identifier saved as an attribute on a Keychain item using kSecAttrType key. +Used for identifying instances of the same type.

    + +
    +

    Default Implementation

    +
    +
    +

    Note

    + The default value is the description of a type conforming to KeychainItem protocol. + +
    +
      static var typeKey: String {
    +      return String(describing: self)
    +  }
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    static var typeKey: String
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + data() + + + Default implementation + +
    +
    +
    +
    +
    +
    +

    The instance data saved as an attribute on a Keychain item using kSecValueData key.

    + +
    +

    Default Implementation

    +
    +
    +

    Note

    + The default value is the encoded instance using the PropertyListEncoder. + +
    +
      func data() throws -> Data {
    +      return try PropertyListEncoder().encode(self)
    +  }
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func data() throws -> Data
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + query(using:) + + + Extension method + +
    +
    +
    +
    +
    +
    +

    Creates and returns KeychainQuery instance object composed from configuration and item data.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal func query(using configuration: Keychain.Configuration) throws -> KeychainQuery
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + configuration + + +
    +

    The configuration of the Keychain.

    +
    +
    +
    +
    +

    Return Value

    +

    The KeychainQuery object.

    +
    +
    +
    +
  • +
  • +
    + + + + query(using:) + + + Extension method + +
    +
    +
    +
    +
    +
    +

    Creates and returns KeychainQuery static object composed from configuration and item data.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal static func query(using configuration: Keychain.Configuration) throws -> KeychainQuery
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + configuration + + +
    +

    The configuration of the Keychain.

    +
    +
    +
    +
    +

    Return Value

    +

    The KeychainQuery object.

    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/Structs.html b/Documentation/Structs.html new file mode 100644 index 0000000..38d2127 --- /dev/null +++ b/Documentation/Structs.html @@ -0,0 +1,122 @@ + + + + Structures Reference + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Structures

+

The following structures are available globally.

+ +
+
+
+
    +
  • +
    + + + + Keychain + +
    +
    +
    +
    +
    +
    +

    Provides and coordinates saving and retrieving data from the Keychain.

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public struct Keychain
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/Structs/Keychain.html b/Documentation/Structs/Keychain.html new file mode 100644 index 0000000..9350462 --- /dev/null +++ b/Documentation/Structs/Keychain.html @@ -0,0 +1,599 @@ + + + + Keychain Structure Reference + + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Keychain

+
+
+
public struct Keychain
+ +
+
+

Provides and coordinates saving and retrieving data from the Keychain.

+ +
+
+
+
    +
  • +
    + + + + access + +
    +
    +
    +
    +
    +
    +

    The access type of the Keychain.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public let access: Keychain.Access
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(access:) + +
    +
    +
    +
    +
    +
    +

    Creates a Keychain instance given the provided parameter(s).

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init(access: Keychain.Access)
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + access + + +
    +

    The access type of the Keychain.

    +
    +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + Access + +
    +
    +
    +
    +
    +
    +

    List of supported access options for configuring Keychain.

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public enum Access
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + Storage + +
    +
    +
    +
    +
    +
    +

    List of supported storage options for Keychain.

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public enum Storage
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + Configuration + +
    +
    +
    +
    +
    +
    +

    A type that represents configuration object for the Keychain instance.

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal struct Configuration
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + delete(_:) + +
    +
    +
    +
    +
    +
    +

    Deletes item from the Keychain.

    +
    +

    Throws

    +

    KeychainError.unhandled containing OSStatus code.

    + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func delete(_ item: KeychainItem) throws
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + item + + +
    +

    The item to delete.

    +
    +
    +
    +
    +
    +
  • +
  • +
    + + + + deleteAll(ofType:) + +
    +
    +
    +
    +
    +
    +

    Deletes all items of specified type.

    +
    +

    Note

    + The implementation of this function directly relies on finding all item instances of specified type first. + +
    + +

    For operation to be successful, make sure Keychain is configured using the correct serviceName and accessGroup. + Also, the following must be true:

    + +
      +
    • Instance types are the same.
    • +
    • Instance storage types are the same.
    • +
    + +

    For more information, see KeychainItem+Query.swift implementation.

    +
    +

    Throws

    +

    KeychainError.unhandled containing OSStatus code.

    + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func deleteAll<T: KeychainItem>(ofType type: T.Type) throws
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + type + + +
    +

    A generic type of the item.

    +
    +
    +
    +
    +
    +
  • +
  • +
    + + + + save(_:) + +
    +
    +
    +
    +
    +
    +

    Saves item to the Keychain.

    +
    +

    Note

    + Saving an identical instance to the Keychain will first remove previously saved instance. + +
    + +

    Item instances are considered identical when the Keychain is configured using the same serviceName and accessGroup. + Also, the following must be true:

    + +
      +
    • Instance types are the same.
    • +
    • Instance storage types are the same.
    • +
    • Instance idKey properties are the same.
    • +
    + +

    For example, consider this implementation:

    +
      struct User: KeychainItem {
    +      let username: String
    +      let password: String
    +
    +      // MARK: KeychainItem
    +
    +      var idKey: String {
    +          return username
    +      }
    +  }
    +
    +
      let userOne = User(username: "user", password: "p-one")
    +  let userTwo = User(username: "user", password: "p-two")
    +
    + +

    Even though these are two distinct instances of User type containing different + passwords, userTwo will be treated as an identical to userOne.

    + +

    For more information, see KeychainItem+Query.swift implementation.

    +
    +

    Throws

    +

    KeychainError if the operation fails.

    + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func save(_ item: KeychainItem) throws
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + item + + +
    +

    The item to save.

    +
    +
    +
    +
    +
    +
  • +
  • +
    + + + + item(ofType:idKey:) + +
    +
    +
    +
    +
    +
    +

    Returns an item for specified account and service group using idKey.

    +
    +

    Throws

    +

    KeychainError if the operation fails.

    + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func item<T: KeychainItem>(ofType type: T.Type, idKey: String) throws -> T?
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + +
    + + type + + +
    +

    A generic type of the item.

    +
    +
    + + idKey + + +
    +

    The unique identifier of the item.

    +
    +
    +
    +
    +

    Return Value

    +

    A newly created item of T.Type if data is found for specified idKey, nil otherwise.

    +
    +
    +
    +
  • +
  • +
    + + + + items(ofType:) + +
    +
    +
    +
    +
    +
    +

    Returns an array of items for specified account and service group.

    +
    +

    Throws

    +

    KeychainError if the operation fails.

    + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func items<T: KeychainItem>(ofType type: T.Type) throws -> [T]?
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + type + + +
    +

    A generic type of the item.

    +
    +
    +
    +
    +

    Return Value

    +

    A newly created items array of T.Type if data is found, nil otherwise.

    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/Structs/Keychain/Access.html b/Documentation/Structs/Keychain/Access.html new file mode 100644 index 0000000..9c378ff --- /dev/null +++ b/Documentation/Structs/Keychain/Access.html @@ -0,0 +1,190 @@ + + + + Access Enumeration Reference + + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Access

+
+
+
public enum Access
+ +
+
+

List of supported access options for configuring Keychain.

+ +
+
+
+
    +
  • +
    + + + + appSpecific + +
    +
    +
    +
    +
    +
    +

    Will configure Keychain to be specific to each app.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    case appSpecific(serviceName: String)
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + groupSpecific + +
    +
    +
    +
    +
    +
    +

    Will configure Keychain to be specific to a group of apps.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    case groupSpecific(accessGroup: String, serviceName: String)
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + configuration + +
    +
    +
    +
    +
    +
    +

    Configuration data for the Keychain instance.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal var configuration: Keychain.Configuration
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/Structs/Keychain/Configuration.html b/Documentation/Structs/Keychain/Configuration.html new file mode 100644 index 0000000..f4fd77d --- /dev/null +++ b/Documentation/Structs/Keychain/Configuration.html @@ -0,0 +1,229 @@ + + + + Configuration Structure Reference + + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Configuration

+
+
+
internal struct Configuration
+ +
+
+

A type that represents configuration object for the Keychain instance.

+ +
+
+
+
    +
  • +
    + + + + accessGroup + +
    +
    +
    +
    +
    +
    +

    The access group if any.

    +
    +

    Note

    +

    Specifying an access group will ensure items are shared across multiple apps using app id prefix. +Not specifying an access group will create items specific to each app.

    + +
    +
    +

    Requires

    +

    A valid app id prefix (can be obtained from Apple Developer portal).

    + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal let accessGroup: String?
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + serviceName + +
    +
    +
    +
    +
    +
    +

    The service name for saving and retrieving data from the Keychain.

    +
    +

    Note

    + Can be set to any string. Typically reflects the app’s name. + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal let serviceName: String
    + +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Creates a Keychain configuration given the provided parameters.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal init(accessGroup: String? = nil, serviceName: String)
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + +
    + + accessGroup + + +
    +

    The access group if any.

    +
    +
    + + serviceName + + +
    +

    The service name.

    +
    +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/Structs/Keychain/Storage.html b/Documentation/Structs/Keychain/Storage.html new file mode 100644 index 0000000..d05979a --- /dev/null +++ b/Documentation/Structs/Keychain/Storage.html @@ -0,0 +1,159 @@ + + + + Storage Enumeration Reference + + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Storage

+
+
+
public enum Storage
+ +
+
+

List of supported storage options for Keychain.

+ +
+
+
+
    +
  • +
    + + + + genericPassword + +
    +
    +
    +
    +
    +
    +

    Item will be stored as encrypted, generic passwords.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    case genericPassword
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + kSecClass + +
    +
    +
    +
    +
    +
    +

    C string value for a given Storage case.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal var kSecClass: CFString
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/Typealiases.html b/Documentation/Typealiases.html new file mode 100644 index 0000000..e647b24 --- /dev/null +++ b/Documentation/Typealiases.html @@ -0,0 +1,121 @@ + + + + Type Aliases Reference + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Type Aliases

+

The following type aliases are available globally.

+ +
+
+
+
    +
  • +
    + + + + KeychainQuery + +
    +
    +
    +
    +
    +
    +

    Represents Keychain query object - dictionary.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal typealias KeychainQuery = [String: AnyObject]
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/badge.svg b/Documentation/badge.svg new file mode 100644 index 0000000..a096fec --- /dev/null +++ b/Documentation/badge.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + documentation + + + documentation + + + 100% + + + 100% + + + diff --git a/Documentation/css/highlight.css b/Documentation/css/highlight.css new file mode 100644 index 0000000..d0db0e1 --- /dev/null +++ b/Documentation/css/highlight.css @@ -0,0 +1,200 @@ +/* Credit to https://gist.github.com/wataru420/2048287 */ +.highlight { + /* Comment */ + /* Error */ + /* Keyword */ + /* Operator */ + /* Comment.Multiline */ + /* Comment.Preproc */ + /* Comment.Single */ + /* Comment.Special */ + /* Generic.Deleted */ + /* Generic.Deleted.Specific */ + /* Generic.Emph */ + /* Generic.Error */ + /* Generic.Heading */ + /* Generic.Inserted */ + /* Generic.Inserted.Specific */ + /* Generic.Output */ + /* Generic.Prompt */ + /* Generic.Strong */ + /* Generic.Subheading */ + /* Generic.Traceback */ + /* Keyword.Constant */ + /* Keyword.Declaration */ + /* Keyword.Pseudo */ + /* Keyword.Reserved */ + /* Keyword.Type */ + /* Literal.Number */ + /* Literal.String */ + /* Name.Attribute */ + /* Name.Builtin */ + /* Name.Class */ + /* Name.Constant */ + /* Name.Entity */ + /* Name.Exception */ + /* Name.Function */ + /* Name.Namespace */ + /* Name.Tag */ + /* Name.Variable */ + /* Operator.Word */ + /* Text.Whitespace */ + /* Literal.Number.Float */ + /* Literal.Number.Hex */ + /* Literal.Number.Integer */ + /* Literal.Number.Oct */ + /* Literal.String.Backtick */ + /* Literal.String.Char */ + /* Literal.String.Doc */ + /* Literal.String.Double */ + /* Literal.String.Escape */ + /* Literal.String.Heredoc */ + /* Literal.String.Interpol */ + /* Literal.String.Other */ + /* Literal.String.Regex */ + /* Literal.String.Single */ + /* Literal.String.Symbol */ + /* Name.Builtin.Pseudo */ + /* Name.Variable.Class */ + /* Name.Variable.Global */ + /* Name.Variable.Instance */ + /* Literal.Number.Integer.Long */ } + .highlight .c { + color: #999988; + font-style: italic; } + .highlight .err { + color: #a61717; + background-color: #e3d2d2; } + .highlight .k { + color: #000000; + font-weight: bold; } + .highlight .o { + color: #000000; + font-weight: bold; } + .highlight .cm { + color: #999988; + font-style: italic; } + .highlight .cp { + color: #999999; + font-weight: bold; } + .highlight .c1 { + color: #999988; + font-style: italic; } + .highlight .cs { + color: #999999; + font-weight: bold; + font-style: italic; } + .highlight .gd { + color: #000000; + background-color: #ffdddd; } + .highlight .gd .x { + color: #000000; + background-color: #ffaaaa; } + .highlight .ge { + color: #000000; + font-style: italic; } + .highlight .gr { + color: #aa0000; } + .highlight .gh { + color: #999999; } + .highlight .gi { + color: #000000; + background-color: #ddffdd; } + .highlight .gi .x { + color: #000000; + background-color: #aaffaa; } + .highlight .go { + color: #888888; } + .highlight .gp { + color: #555555; } + .highlight .gs { + font-weight: bold; } + .highlight .gu { + color: #aaaaaa; } + .highlight .gt { + color: #aa0000; } + .highlight .kc { + color: #000000; + font-weight: bold; } + .highlight .kd { + color: #000000; + font-weight: bold; } + .highlight .kp { + color: #000000; + font-weight: bold; } + .highlight .kr { + color: #000000; + font-weight: bold; } + .highlight .kt { + color: #445588; } + .highlight .m { + color: #009999; } + .highlight .s { + color: #d14; } + .highlight .na { + color: #008080; } + .highlight .nb { + color: #0086B3; } + .highlight .nc { + color: #445588; + font-weight: bold; } + .highlight .no { + color: #008080; } + .highlight .ni { + color: #800080; } + .highlight .ne { + color: #990000; + font-weight: bold; } + .highlight .nf { + color: #990000; } + .highlight .nn { + color: #555555; } + .highlight .nt { + color: #000080; } + .highlight .nv { + color: #008080; } + .highlight .ow { + color: #000000; + font-weight: bold; } + .highlight .w { + color: #bbbbbb; } + .highlight .mf { + color: #009999; } + .highlight .mh { + color: #009999; } + .highlight .mi { + color: #009999; } + .highlight .mo { + color: #009999; } + .highlight .sb { + color: #d14; } + .highlight .sc { + color: #d14; } + .highlight .sd { + color: #d14; } + .highlight .s2 { + color: #d14; } + .highlight .se { + color: #d14; } + .highlight .sh { + color: #d14; } + .highlight .si { + color: #d14; } + .highlight .sx { + color: #d14; } + .highlight .sr { + color: #009926; } + .highlight .s1 { + color: #d14; } + .highlight .ss { + color: #990073; } + .highlight .bp { + color: #999999; } + .highlight .vc { + color: #008080; } + .highlight .vg { + color: #008080; } + .highlight .vi { + color: #008080; } + .highlight .il { + color: #009999; } diff --git a/Documentation/css/jazzy.css b/Documentation/css/jazzy.css new file mode 100644 index 0000000..d628282 --- /dev/null +++ b/Documentation/css/jazzy.css @@ -0,0 +1,337 @@ +html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { + background: transparent; + border: 0; + margin: 0; + outline: 0; + padding: 0; + vertical-align: baseline; } + +body { + background-color: #f2f2f2; + font-family: Helvetica, freesans, Arial, sans-serif; + font-size: 14px; + -webkit-font-smoothing: subpixel-antialiased; + word-wrap: break-word; } + +h1, h2, h3 { + margin-top: 0.8em; + margin-bottom: 0.3em; + font-weight: 100; + color: black; } + +h1 { + font-size: 2.5em; } + +h2 { + font-size: 2em; + border-bottom: 1px solid #e2e2e2; } + +h4 { + font-size: 13px; + line-height: 1.5; + margin-top: 21px; } + +h5 { + font-size: 1.1em; } + +h6 { + font-size: 1.1em; + color: #777; } + +.section-name { + color: gray; + display: block; + font-family: Helvetica; + font-size: 22px; + font-weight: 100; + margin-bottom: 15px; } + +pre, code { + font: 0.95em Menlo, monospace; + color: #777; + word-wrap: normal; } + +p code, li code { + background-color: #eee; + padding: 2px 4px; + border-radius: 4px; } + +a { + color: #0088cc; + text-decoration: none; } + +ul { + padding-left: 15px; } + +li { + line-height: 1.8em; } + +img { + max-width: 100%; } + +blockquote { + margin-left: 0; + padding: 0 10px; + border-left: 4px solid #ccc; } + +.content-wrapper { + margin: 0 auto; + width: 980px; } + +header { + font-size: 0.85em; + line-height: 26px; + background-color: #414141; + position: fixed; + width: 100%; + z-index: 1; } + header img { + padding-right: 6px; + vertical-align: -4px; + height: 16px; } + header a { + color: #fff; } + header p { + float: left; + color: #999; } + header .header-right { + float: right; + margin-left: 16px; } + +#breadcrumbs { + background-color: #f2f2f2; + height: 27px; + padding-top: 17px; + position: fixed; + width: 100%; + z-index: 1; + margin-top: 26px; } + #breadcrumbs #carat { + height: 10px; + margin: 0 5px; } + +.sidebar { + background-color: #f9f9f9; + border: 1px solid #e2e2e2; + overflow-y: auto; + overflow-x: hidden; + position: fixed; + top: 70px; + bottom: 0; + width: 230px; + word-wrap: normal; } + +.nav-groups { + list-style-type: none; + background: #fff; + padding-left: 0; } + +.nav-group-name { + border-bottom: 1px solid #e2e2e2; + font-size: 1.1em; + font-weight: 100; + padding: 15px 0 15px 20px; } + .nav-group-name > a { + color: #333; } + +.nav-group-tasks { + margin-top: 5px; } + +.nav-group-task { + font-size: 0.9em; + list-style-type: none; + white-space: nowrap; } + .nav-group-task a { + color: #888; } + +.main-content { + background-color: #fff; + border: 1px solid #e2e2e2; + margin-left: 246px; + position: absolute; + overflow: hidden; + padding-bottom: 60px; + top: 70px; + width: 734px; } + .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { + margin-bottom: 1em; } + .main-content p { + line-height: 1.8em; } + .main-content section .section:first-child { + margin-top: 0; + padding-top: 0; } + .main-content section .task-group-section .task-group:first-of-type { + padding-top: 10px; } + .main-content section .task-group-section .task-group:first-of-type .section-name { + padding-top: 15px; } + .main-content section .heading:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + +.section { + padding: 0 25px; } + +.highlight { + background-color: #eee; + padding: 10px 12px; + border: 1px solid #e2e2e2; + border-radius: 4px; + overflow-x: auto; } + +.declaration .highlight { + overflow-x: initial; + padding: 0 40px 40px 0; + margin-bottom: -25px; + background-color: transparent; + border: none; } + +.section-name { + margin: 0; + margin-left: 18px; } + +.task-group-section { + padding-left: 6px; + border-top: 1px solid #e2e2e2; } + +.task-group { + padding-top: 0px; } + +.task-name-container a[name]:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + +.item { + padding-top: 8px; + width: 100%; + list-style-type: none; } + .item a[name]:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + .item code { + background-color: transparent; + padding: 0; } + .item .token { + padding-left: 3px; + margin-left: 15px; + font-size: 11.9px; } + .item .declaration-note { + font-size: .85em; + color: gray; + font-style: italic; } + +.pointer-container { + border-bottom: 1px solid #e2e2e2; + left: -23px; + padding-bottom: 13px; + position: relative; + width: 110%; } + +.pointer { + background: #f9f9f9; + border-left: 1px solid #e2e2e2; + border-top: 1px solid #e2e2e2; + height: 12px; + left: 21px; + top: -7px; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + position: absolute; + width: 12px; } + +.height-container { + display: none; + left: -25px; + padding: 0 25px; + position: relative; + width: 100%; + overflow: hidden; } + .height-container .section { + background: #f9f9f9; + border-bottom: 1px solid #e2e2e2; + left: -25px; + position: relative; + width: 100%; + padding-top: 10px; + padding-bottom: 5px; } + +.aside, .language { + padding: 6px 12px; + margin: 12px 0; + border-left: 5px solid #dddddd; + overflow-y: hidden; } + .aside .aside-title, .language .aside-title { + font-size: 9px; + letter-spacing: 2px; + text-transform: uppercase; + padding-bottom: 0; + margin: 0; + color: #aaa; + -webkit-user-select: none; } + .aside p:last-child, .language p:last-child { + margin-bottom: 0; } + +.language { + border-left: 5px solid #cde9f4; } + .language .aside-title { + color: #4b8afb; } + +.aside-warning { + border-left: 5px solid #ff6666; } + .aside-warning .aside-title { + color: #ff0000; } + +.graybox { + border-collapse: collapse; + width: 100%; } + .graybox p { + margin: 0; + word-break: break-word; + min-width: 50px; } + .graybox td { + border: 1px solid #e2e2e2; + padding: 5px 25px 5px 10px; + vertical-align: middle; } + .graybox tr td:first-of-type { + text-align: right; + padding: 7px; + vertical-align: top; + word-break: normal; + width: 40px; } + +.slightly-smaller { + font-size: 0.9em; } + +#footer { + position: absolute; + bottom: 10px; + margin-left: 25px; } + #footer p { + margin: 0; + color: #aaa; + font-size: 0.8em; } + +html.dash header, html.dash #breadcrumbs, html.dash .sidebar { + display: none; } +html.dash .main-content { + width: 980px; + margin-left: 0; + border: none; + width: 100%; + top: 0; + padding-bottom: 0; } +html.dash .height-container { + display: block; } +html.dash .item .token { + margin-left: 0; } +html.dash .content-wrapper { + width: auto; } +html.dash #footer { + position: static; } diff --git a/Documentation/docs.sh b/Documentation/docs.sh new file mode 100755 index 0000000..c965f2b --- /dev/null +++ b/Documentation/docs.sh @@ -0,0 +1,8 @@ +#!/bin/sh +cd ../Framework; +jazzy --min-acl internal --module Keychain --exclude=Keychain/Extensions/Foundation*,Keychain/Extensions/Framework/Keychain/Keychain+Manager.swift; +rm -rf build; +cd docs; +cp -r * ../../Documentation +cd ..; +rm -rf docs; diff --git a/Documentation/docsets/Keychain.docset/Contents/Info.plist b/Documentation/docsets/Keychain.docset/Contents/Info.plist new file mode 100644 index 0000000..0ab59fd --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleIdentifier + com.jazzy.keychain + CFBundleName + Keychain + DocSetPlatformFamily + keychain + isDashDocset + + dashIndexFilePath + index.html + isJavaScriptEnabled + + DashDocSetFamily + dashtoc + + diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Enums.html b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Enums.html new file mode 100644 index 0000000..4a589bd --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Enums.html @@ -0,0 +1,122 @@ + + + + Enumerations Reference + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Enumerations

+

The following enumerations are available globally.

+ +
+
+
+
    +
  • +
    + + + + KeychainError + +
    +
    +
    +
    +
    +
    +

    List of possible error cases thrown by Keychain operations.

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public enum KeychainError: Error
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Enums/KeychainError.html b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Enums/KeychainError.html new file mode 100644 index 0000000..db35e9d --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Enums/KeychainError.html @@ -0,0 +1,166 @@ + + + + KeychainError Enumeration Reference + + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

KeychainError

+
+
+
public enum KeychainError: Error
+ +
+
+

List of possible error cases thrown by Keychain operations.

+ +
+
+
+
    +
  • +
    + + + + unexpectedItemData + +
    +
    +
    +
    +
    +
    +

    Keychain search returned unexpected item data.

    +
    +

    Note

    + Only thrown when retrieving items from the Keychain fails due to SecItemCopyMatching query returning anything but an array of [String: AnyObject]. + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    case unexpectedItemData
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + unhandled + +
    +
    +
    +
    +
    +
    +

    Unhandled error returned by Keychain operation.

    + +

    For list of OSStatus codes, please see https://www.osstatus.com/

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    case unhandled(OSStatus)
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Protocols.html b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Protocols.html new file mode 100644 index 0000000..d795af8 --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Protocols.html @@ -0,0 +1,122 @@ + + + + Protocols Reference + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Protocols

+

The following protocols are available globally.

+ +
+
+
+
    +
  • +
    + + + + KeychainItem + +
    +
    +
    +
    +
    +
    +

    A type that can represent conforming model as a KeychainItem.

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public protocol KeychainItem: Codable
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Protocols/KeychainItem.html b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Protocols/KeychainItem.html new file mode 100644 index 0000000..99aa05b --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Protocols/KeychainItem.html @@ -0,0 +1,478 @@ + + + + KeychainItem Protocol Reference + + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

KeychainItem

+
+
+
public protocol KeychainItem: Codable
+ +
+
+

A type that can represent conforming model as a KeychainItem.

+ +
+
+
+
    +
  • +
    + + + + comment + + + Default implementation + +
    +
    +
    +
    +
    +
    +

    The instance comment saved as an attribute on a Keychain item using kSecAttrComment key.

    + +
    +

    Default Implementation

    +
    +
    +

    Note

    + The default valus is nil. + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    var comment: String?
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + description + + + Default implementation + +
    +
    +
    +
    +
    +
    +

    The instance description saved as an attribute on a Keychain item using kSecAttrDescription key.

    + +
    +

    Default Implementation

    +
    +
    +

    Note

    + The default valus is nil. + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    var description: String?
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + idKey + +
    +
    +
    +
    +
    +
    +

    The instance identifier saved as an attribute on a Keychain item using kSecAttrAccount key.

    +
    +

    Warning

    +

    If you intend to store multiple instances of the same type, idKey must be unique to each instance. +Failing to do so will result in having previously saved instance maching this idKey overriden.

    + +
    +
  • Consider this implementation:

    +
    struct User: KeychainItem {
    +  let email: String
    +
    +  // MARK: KeychainItem
    +
    +  var idKey: String {
    +      return email
    +  }
    +}
    +
    + +

    In the above example, the idKey is set to be the email address of the user. +You can use the idKey later to perform a search like this:

  • +
      try keychain.item(ofType: User.self, idKey: "email@alaskaair.com")
    +
    + +

    If only a single instance of a type will be stored, the idKey can be set using typeKey.

    +
      struct SSOCredential: KeychainItem {
    +      let accessToken: String
    +
    +      // MARK: KeychainItem
    +
    +      var idKey: String {
    +          return SSOCredential.typeKey
    +      }
    +  }
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    var idKey: String
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + storage + + + Default implementation + +
    +
    +
    +
    +
    +
    +

    The storage option of the item for specifying Keychain storage type using kSecClass key.

    + +
    +

    Default Implementation

    +
    +
    +

    Note

    + The default value is .genericPassword. + +
    + +

    This Keychain framework only supports kSecClassGenericPassword for now.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    static var storage: Keychain.Storage
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + typeKey + + + Default implementation + +
    +
    +
    +
    +
    +
    +

    The type identifier saved as an attribute on a Keychain item using kSecAttrType key. +Used for identifying instances of the same type.

    + +
    +

    Default Implementation

    +
    +
    +

    Note

    + The default value is the description of a type conforming to KeychainItem protocol. + +
    +
      static var typeKey: String {
    +      return String(describing: self)
    +  }
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    static var typeKey: String
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + data() + + + Default implementation + +
    +
    +
    +
    +
    +
    +

    The instance data saved as an attribute on a Keychain item using kSecValueData key.

    + +
    +

    Default Implementation

    +
    +
    +

    Note

    + The default value is the encoded instance using the PropertyListEncoder. + +
    +
      func data() throws -> Data {
    +      return try PropertyListEncoder().encode(self)
    +  }
    +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    func data() throws -> Data
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + query(using:) + + + Extension method + +
    +
    +
    +
    +
    +
    +

    Creates and returns KeychainQuery instance object composed from configuration and item data.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal func query(using configuration: Keychain.Configuration) throws -> KeychainQuery
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + configuration + + +
    +

    The configuration of the Keychain.

    +
    +
    +
    +
    +

    Return Value

    +

    The KeychainQuery object.

    +
    +
    +
    +
  • +
  • +
    + + + + query(using:) + + + Extension method + +
    +
    +
    +
    +
    +
    +

    Creates and returns KeychainQuery static object composed from configuration and item data.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal static func query(using configuration: Keychain.Configuration) throws -> KeychainQuery
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + configuration + + +
    +

    The configuration of the Keychain.

    +
    +
    +
    +
    +

    Return Value

    +

    The KeychainQuery object.

    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs.html b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs.html new file mode 100644 index 0000000..38d2127 --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs.html @@ -0,0 +1,122 @@ + + + + Structures Reference + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Structures

+

The following structures are available globally.

+ +
+
+
+
    +
  • +
    + + + + Keychain + +
    +
    +
    +
    +
    +
    +

    Provides and coordinates saving and retrieving data from the Keychain.

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public struct Keychain
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain.html b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain.html new file mode 100644 index 0000000..9350462 --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain.html @@ -0,0 +1,599 @@ + + + + Keychain Structure Reference + + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Keychain

+
+
+
public struct Keychain
+ +
+
+

Provides and coordinates saving and retrieving data from the Keychain.

+ +
+
+
+
    +
  • +
    + + + + access + +
    +
    +
    +
    +
    +
    +

    The access type of the Keychain.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public let access: Keychain.Access
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + init(access:) + +
    +
    +
    +
    +
    +
    +

    Creates a Keychain instance given the provided parameter(s).

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public init(access: Keychain.Access)
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + access + + +
    +

    The access type of the Keychain.

    +
    +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + Access + +
    +
    +
    +
    +
    +
    +

    List of supported access options for configuring Keychain.

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public enum Access
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + Storage + +
    +
    +
    +
    +
    +
    +

    List of supported storage options for Keychain.

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public enum Storage
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + Configuration + +
    +
    +
    +
    +
    +
    +

    A type that represents configuration object for the Keychain instance.

    + + See more +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal struct Configuration
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + delete(_:) + +
    +
    +
    +
    +
    +
    +

    Deletes item from the Keychain.

    +
    +

    Throws

    +

    KeychainError.unhandled containing OSStatus code.

    + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func delete(_ item: KeychainItem) throws
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + item + + +
    +

    The item to delete.

    +
    +
    +
    +
    +
    +
  • +
  • +
    + + + + deleteAll(ofType:) + +
    +
    +
    +
    +
    +
    +

    Deletes all items of specified type.

    +
    +

    Note

    + The implementation of this function directly relies on finding all item instances of specified type first. + +
    + +

    For operation to be successful, make sure Keychain is configured using the correct serviceName and accessGroup. + Also, the following must be true:

    + +
      +
    • Instance types are the same.
    • +
    • Instance storage types are the same.
    • +
    + +

    For more information, see KeychainItem+Query.swift implementation.

    +
    +

    Throws

    +

    KeychainError.unhandled containing OSStatus code.

    + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func deleteAll<T: KeychainItem>(ofType type: T.Type) throws
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + type + + +
    +

    A generic type of the item.

    +
    +
    +
    +
    +
    +
  • +
  • +
    + + + + save(_:) + +
    +
    +
    +
    +
    +
    +

    Saves item to the Keychain.

    +
    +

    Note

    + Saving an identical instance to the Keychain will first remove previously saved instance. + +
    + +

    Item instances are considered identical when the Keychain is configured using the same serviceName and accessGroup. + Also, the following must be true:

    + +
      +
    • Instance types are the same.
    • +
    • Instance storage types are the same.
    • +
    • Instance idKey properties are the same.
    • +
    + +

    For example, consider this implementation:

    +
      struct User: KeychainItem {
    +      let username: String
    +      let password: String
    +
    +      // MARK: KeychainItem
    +
    +      var idKey: String {
    +          return username
    +      }
    +  }
    +
    +
      let userOne = User(username: "user", password: "p-one")
    +  let userTwo = User(username: "user", password: "p-two")
    +
    + +

    Even though these are two distinct instances of User type containing different + passwords, userTwo will be treated as an identical to userOne.

    + +

    For more information, see KeychainItem+Query.swift implementation.

    +
    +

    Throws

    +

    KeychainError if the operation fails.

    + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func save(_ item: KeychainItem) throws
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + item + + +
    +

    The item to save.

    +
    +
    +
    +
    +
    +
  • +
  • +
    + + + + item(ofType:idKey:) + +
    +
    +
    +
    +
    +
    +

    Returns an item for specified account and service group using idKey.

    +
    +

    Throws

    +

    KeychainError if the operation fails.

    + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func item<T: KeychainItem>(ofType type: T.Type, idKey: String) throws -> T?
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + +
    + + type + + +
    +

    A generic type of the item.

    +
    +
    + + idKey + + +
    +

    The unique identifier of the item.

    +
    +
    +
    +
    +

    Return Value

    +

    A newly created item of T.Type if data is found for specified idKey, nil otherwise.

    +
    +
    +
    +
  • +
  • +
    + + + + items(ofType:) + +
    +
    +
    +
    +
    +
    +

    Returns an array of items for specified account and service group.

    +
    +

    Throws

    +

    KeychainError if the operation fails.

    + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public func items<T: KeychainItem>(ofType type: T.Type) throws -> [T]?
    + +
    +
    +
    +

    Parameters

    + + + + + + + +
    + + type + + +
    +

    A generic type of the item.

    +
    +
    +
    +
    +

    Return Value

    +

    A newly created items array of T.Type if data is found, nil otherwise.

    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain/Access.html b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain/Access.html new file mode 100644 index 0000000..9c378ff --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain/Access.html @@ -0,0 +1,190 @@ + + + + Access Enumeration Reference + + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Access

+
+
+
public enum Access
+ +
+
+

List of supported access options for configuring Keychain.

+ +
+
+
+
    +
  • +
    + + + + appSpecific + +
    +
    +
    +
    +
    +
    +

    Will configure Keychain to be specific to each app.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    case appSpecific(serviceName: String)
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + groupSpecific + +
    +
    +
    +
    +
    +
    +

    Will configure Keychain to be specific to a group of apps.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    case groupSpecific(accessGroup: String, serviceName: String)
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + configuration + +
    +
    +
    +
    +
    +
    +

    Configuration data for the Keychain instance.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal var configuration: Keychain.Configuration
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain/Configuration.html b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain/Configuration.html new file mode 100644 index 0000000..f4fd77d --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain/Configuration.html @@ -0,0 +1,229 @@ + + + + Configuration Structure Reference + + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Configuration

+
+
+
internal struct Configuration
+ +
+
+

A type that represents configuration object for the Keychain instance.

+ +
+
+
+
    +
  • +
    + + + + accessGroup + +
    +
    +
    +
    +
    +
    +

    The access group if any.

    +
    +

    Note

    +

    Specifying an access group will ensure items are shared across multiple apps using app id prefix. +Not specifying an access group will create items specific to each app.

    + +
    +
    +

    Requires

    +

    A valid app id prefix (can be obtained from Apple Developer portal).

    + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal let accessGroup: String?
    + +
    +
    +
    +
    +
  • +
  • +
    + + + + serviceName + +
    +
    +
    +
    +
    +
    +

    The service name for saving and retrieving data from the Keychain.

    +
    +

    Note

    + Can be set to any string. Typically reflects the app’s name. + +
    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal let serviceName: String
    + +
    +
    +
    +
    +
  • +
  • + +
    +
    +
    +
    +
    +

    Creates a Keychain configuration given the provided parameters.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal init(accessGroup: String? = nil, serviceName: String)
    + +
    +
    +
    +

    Parameters

    + + + + + + + + + + + +
    + + accessGroup + + +
    +

    The access group if any.

    +
    +
    + + serviceName + + +
    +

    The service name.

    +
    +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain/Storage.html b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain/Storage.html new file mode 100644 index 0000000..d05979a --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Structs/Keychain/Storage.html @@ -0,0 +1,159 @@ + + + + Storage Enumeration Reference + + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Storage

+
+
+
public enum Storage
+ +
+
+

List of supported storage options for Keychain.

+ +
+
+
+
    +
  • +
    + + + + genericPassword + +
    +
    +
    +
    +
    +
    +

    Item will be stored as encrypted, generic passwords.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    case genericPassword
    + +
    +
    +
    +
    +
  • +
+
+
+
    +
  • +
    + + + + kSecClass + +
    +
    +
    +
    +
    +
    +

    C string value for a given Storage case.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal var kSecClass: CFString
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Typealiases.html b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Typealiases.html new file mode 100644 index 0000000..e647b24 --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/Typealiases.html @@ -0,0 +1,121 @@ + + + + Type Aliases Reference + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+

Type Aliases

+

The following type aliases are available globally.

+ +
+
+
+
    +
  • +
    + + + + KeychainQuery + +
    +
    +
    +
    +
    +
    +

    Represents Keychain query object - dictionary.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    internal typealias KeychainQuery = [String: AnyObject]
    + +
    +
    +
    +
    +
  • +
+
+
+
+ +
+
+ + + diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/badge.svg b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/badge.svg new file mode 100644 index 0000000..a096fec --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/badge.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + documentation + + + documentation + + + 100% + + + 100% + + + diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/css/highlight.css b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/css/highlight.css new file mode 100644 index 0000000..d0db0e1 --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/css/highlight.css @@ -0,0 +1,200 @@ +/* Credit to https://gist.github.com/wataru420/2048287 */ +.highlight { + /* Comment */ + /* Error */ + /* Keyword */ + /* Operator */ + /* Comment.Multiline */ + /* Comment.Preproc */ + /* Comment.Single */ + /* Comment.Special */ + /* Generic.Deleted */ + /* Generic.Deleted.Specific */ + /* Generic.Emph */ + /* Generic.Error */ + /* Generic.Heading */ + /* Generic.Inserted */ + /* Generic.Inserted.Specific */ + /* Generic.Output */ + /* Generic.Prompt */ + /* Generic.Strong */ + /* Generic.Subheading */ + /* Generic.Traceback */ + /* Keyword.Constant */ + /* Keyword.Declaration */ + /* Keyword.Pseudo */ + /* Keyword.Reserved */ + /* Keyword.Type */ + /* Literal.Number */ + /* Literal.String */ + /* Name.Attribute */ + /* Name.Builtin */ + /* Name.Class */ + /* Name.Constant */ + /* Name.Entity */ + /* Name.Exception */ + /* Name.Function */ + /* Name.Namespace */ + /* Name.Tag */ + /* Name.Variable */ + /* Operator.Word */ + /* Text.Whitespace */ + /* Literal.Number.Float */ + /* Literal.Number.Hex */ + /* Literal.Number.Integer */ + /* Literal.Number.Oct */ + /* Literal.String.Backtick */ + /* Literal.String.Char */ + /* Literal.String.Doc */ + /* Literal.String.Double */ + /* Literal.String.Escape */ + /* Literal.String.Heredoc */ + /* Literal.String.Interpol */ + /* Literal.String.Other */ + /* Literal.String.Regex */ + /* Literal.String.Single */ + /* Literal.String.Symbol */ + /* Name.Builtin.Pseudo */ + /* Name.Variable.Class */ + /* Name.Variable.Global */ + /* Name.Variable.Instance */ + /* Literal.Number.Integer.Long */ } + .highlight .c { + color: #999988; + font-style: italic; } + .highlight .err { + color: #a61717; + background-color: #e3d2d2; } + .highlight .k { + color: #000000; + font-weight: bold; } + .highlight .o { + color: #000000; + font-weight: bold; } + .highlight .cm { + color: #999988; + font-style: italic; } + .highlight .cp { + color: #999999; + font-weight: bold; } + .highlight .c1 { + color: #999988; + font-style: italic; } + .highlight .cs { + color: #999999; + font-weight: bold; + font-style: italic; } + .highlight .gd { + color: #000000; + background-color: #ffdddd; } + .highlight .gd .x { + color: #000000; + background-color: #ffaaaa; } + .highlight .ge { + color: #000000; + font-style: italic; } + .highlight .gr { + color: #aa0000; } + .highlight .gh { + color: #999999; } + .highlight .gi { + color: #000000; + background-color: #ddffdd; } + .highlight .gi .x { + color: #000000; + background-color: #aaffaa; } + .highlight .go { + color: #888888; } + .highlight .gp { + color: #555555; } + .highlight .gs { + font-weight: bold; } + .highlight .gu { + color: #aaaaaa; } + .highlight .gt { + color: #aa0000; } + .highlight .kc { + color: #000000; + font-weight: bold; } + .highlight .kd { + color: #000000; + font-weight: bold; } + .highlight .kp { + color: #000000; + font-weight: bold; } + .highlight .kr { + color: #000000; + font-weight: bold; } + .highlight .kt { + color: #445588; } + .highlight .m { + color: #009999; } + .highlight .s { + color: #d14; } + .highlight .na { + color: #008080; } + .highlight .nb { + color: #0086B3; } + .highlight .nc { + color: #445588; + font-weight: bold; } + .highlight .no { + color: #008080; } + .highlight .ni { + color: #800080; } + .highlight .ne { + color: #990000; + font-weight: bold; } + .highlight .nf { + color: #990000; } + .highlight .nn { + color: #555555; } + .highlight .nt { + color: #000080; } + .highlight .nv { + color: #008080; } + .highlight .ow { + color: #000000; + font-weight: bold; } + .highlight .w { + color: #bbbbbb; } + .highlight .mf { + color: #009999; } + .highlight .mh { + color: #009999; } + .highlight .mi { + color: #009999; } + .highlight .mo { + color: #009999; } + .highlight .sb { + color: #d14; } + .highlight .sc { + color: #d14; } + .highlight .sd { + color: #d14; } + .highlight .s2 { + color: #d14; } + .highlight .se { + color: #d14; } + .highlight .sh { + color: #d14; } + .highlight .si { + color: #d14; } + .highlight .sx { + color: #d14; } + .highlight .sr { + color: #009926; } + .highlight .s1 { + color: #d14; } + .highlight .ss { + color: #990073; } + .highlight .bp { + color: #999999; } + .highlight .vc { + color: #008080; } + .highlight .vg { + color: #008080; } + .highlight .vi { + color: #008080; } + .highlight .il { + color: #009999; } diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/css/jazzy.css b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/css/jazzy.css new file mode 100644 index 0000000..d628282 --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/css/jazzy.css @@ -0,0 +1,337 @@ +html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { + background: transparent; + border: 0; + margin: 0; + outline: 0; + padding: 0; + vertical-align: baseline; } + +body { + background-color: #f2f2f2; + font-family: Helvetica, freesans, Arial, sans-serif; + font-size: 14px; + -webkit-font-smoothing: subpixel-antialiased; + word-wrap: break-word; } + +h1, h2, h3 { + margin-top: 0.8em; + margin-bottom: 0.3em; + font-weight: 100; + color: black; } + +h1 { + font-size: 2.5em; } + +h2 { + font-size: 2em; + border-bottom: 1px solid #e2e2e2; } + +h4 { + font-size: 13px; + line-height: 1.5; + margin-top: 21px; } + +h5 { + font-size: 1.1em; } + +h6 { + font-size: 1.1em; + color: #777; } + +.section-name { + color: gray; + display: block; + font-family: Helvetica; + font-size: 22px; + font-weight: 100; + margin-bottom: 15px; } + +pre, code { + font: 0.95em Menlo, monospace; + color: #777; + word-wrap: normal; } + +p code, li code { + background-color: #eee; + padding: 2px 4px; + border-radius: 4px; } + +a { + color: #0088cc; + text-decoration: none; } + +ul { + padding-left: 15px; } + +li { + line-height: 1.8em; } + +img { + max-width: 100%; } + +blockquote { + margin-left: 0; + padding: 0 10px; + border-left: 4px solid #ccc; } + +.content-wrapper { + margin: 0 auto; + width: 980px; } + +header { + font-size: 0.85em; + line-height: 26px; + background-color: #414141; + position: fixed; + width: 100%; + z-index: 1; } + header img { + padding-right: 6px; + vertical-align: -4px; + height: 16px; } + header a { + color: #fff; } + header p { + float: left; + color: #999; } + header .header-right { + float: right; + margin-left: 16px; } + +#breadcrumbs { + background-color: #f2f2f2; + height: 27px; + padding-top: 17px; + position: fixed; + width: 100%; + z-index: 1; + margin-top: 26px; } + #breadcrumbs #carat { + height: 10px; + margin: 0 5px; } + +.sidebar { + background-color: #f9f9f9; + border: 1px solid #e2e2e2; + overflow-y: auto; + overflow-x: hidden; + position: fixed; + top: 70px; + bottom: 0; + width: 230px; + word-wrap: normal; } + +.nav-groups { + list-style-type: none; + background: #fff; + padding-left: 0; } + +.nav-group-name { + border-bottom: 1px solid #e2e2e2; + font-size: 1.1em; + font-weight: 100; + padding: 15px 0 15px 20px; } + .nav-group-name > a { + color: #333; } + +.nav-group-tasks { + margin-top: 5px; } + +.nav-group-task { + font-size: 0.9em; + list-style-type: none; + white-space: nowrap; } + .nav-group-task a { + color: #888; } + +.main-content { + background-color: #fff; + border: 1px solid #e2e2e2; + margin-left: 246px; + position: absolute; + overflow: hidden; + padding-bottom: 60px; + top: 70px; + width: 734px; } + .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { + margin-bottom: 1em; } + .main-content p { + line-height: 1.8em; } + .main-content section .section:first-child { + margin-top: 0; + padding-top: 0; } + .main-content section .task-group-section .task-group:first-of-type { + padding-top: 10px; } + .main-content section .task-group-section .task-group:first-of-type .section-name { + padding-top: 15px; } + .main-content section .heading:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + +.section { + padding: 0 25px; } + +.highlight { + background-color: #eee; + padding: 10px 12px; + border: 1px solid #e2e2e2; + border-radius: 4px; + overflow-x: auto; } + +.declaration .highlight { + overflow-x: initial; + padding: 0 40px 40px 0; + margin-bottom: -25px; + background-color: transparent; + border: none; } + +.section-name { + margin: 0; + margin-left: 18px; } + +.task-group-section { + padding-left: 6px; + border-top: 1px solid #e2e2e2; } + +.task-group { + padding-top: 0px; } + +.task-name-container a[name]:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + +.item { + padding-top: 8px; + width: 100%; + list-style-type: none; } + .item a[name]:before { + content: ""; + display: block; + padding-top: 70px; + margin: -70px 0 0; } + .item code { + background-color: transparent; + padding: 0; } + .item .token { + padding-left: 3px; + margin-left: 15px; + font-size: 11.9px; } + .item .declaration-note { + font-size: .85em; + color: gray; + font-style: italic; } + +.pointer-container { + border-bottom: 1px solid #e2e2e2; + left: -23px; + padding-bottom: 13px; + position: relative; + width: 110%; } + +.pointer { + background: #f9f9f9; + border-left: 1px solid #e2e2e2; + border-top: 1px solid #e2e2e2; + height: 12px; + left: 21px; + top: -7px; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + position: absolute; + width: 12px; } + +.height-container { + display: none; + left: -25px; + padding: 0 25px; + position: relative; + width: 100%; + overflow: hidden; } + .height-container .section { + background: #f9f9f9; + border-bottom: 1px solid #e2e2e2; + left: -25px; + position: relative; + width: 100%; + padding-top: 10px; + padding-bottom: 5px; } + +.aside, .language { + padding: 6px 12px; + margin: 12px 0; + border-left: 5px solid #dddddd; + overflow-y: hidden; } + .aside .aside-title, .language .aside-title { + font-size: 9px; + letter-spacing: 2px; + text-transform: uppercase; + padding-bottom: 0; + margin: 0; + color: #aaa; + -webkit-user-select: none; } + .aside p:last-child, .language p:last-child { + margin-bottom: 0; } + +.language { + border-left: 5px solid #cde9f4; } + .language .aside-title { + color: #4b8afb; } + +.aside-warning { + border-left: 5px solid #ff6666; } + .aside-warning .aside-title { + color: #ff0000; } + +.graybox { + border-collapse: collapse; + width: 100%; } + .graybox p { + margin: 0; + word-break: break-word; + min-width: 50px; } + .graybox td { + border: 1px solid #e2e2e2; + padding: 5px 25px 5px 10px; + vertical-align: middle; } + .graybox tr td:first-of-type { + text-align: right; + padding: 7px; + vertical-align: top; + word-break: normal; + width: 40px; } + +.slightly-smaller { + font-size: 0.9em; } + +#footer { + position: absolute; + bottom: 10px; + margin-left: 25px; } + #footer p { + margin: 0; + color: #aaa; + font-size: 0.8em; } + +html.dash header, html.dash #breadcrumbs, html.dash .sidebar { + display: none; } +html.dash .main-content { + width: 980px; + margin-left: 0; + border: none; + width: 100%; + top: 0; + padding-bottom: 0; } +html.dash .height-container { + display: block; } +html.dash .item .token { + margin-left: 0; } +html.dash .content-wrapper { + width: auto; } +html.dash #footer { + position: static; } diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/img/carat.png b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/img/carat.png new file mode 100755 index 0000000000000000000000000000000000000000..29d2f7fd4955fca6bc6fb740e0373a2c358c398e GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRo!3HEV4DF?Wlw^r(L`iUdT1k0gQ7VIDN`6wR zf@f}GdTLN=VoGJ<$y6JlqAi{-jv*Ddl5#RKJQ5NTUZgiPI4RUKGIKU?u8L&ndhX1t za+0CMVUnT(Gnb}ei=c~x==tMH^F1_tBocXwcoSWoO-SZY-o>!8%^=Bms)(~h;m_U( zXNixk28L}0LS5-jKyq@#2gyS|J&f#pGCLkTc<@2s1dqeyqJ*Rc0tSIETAgmODY;(s z2y|Mcp&2}7rpBprBBB~1qM1`N+}4SoxYVPqsXi&l`rxZp{(w0iSy$Nv5*Vy!RapG^ S^0y4=eg;ohKbLh*2~7a!Pg}VF literal 0 HcmV?d00001 diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/img/dash.png b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/img/dash.png new file mode 100755 index 0000000000000000000000000000000000000000..6f694c7a012b417908da3687a0a39aa182e91c74 GIT binary patch literal 1338 zcmaJ>U2NM_6t){^r>#wcfL0VSTvuX@)$vd4#5N6WVkc|1rR}naMb)(7I5(};#!el# zbtCASsp?W-qE8zSJoFVdA%-T$WL8RI_B? zd+t5o`T5Q{p6=<|U$?VqCxRe#u}(PwSIl{LRKstfSbPYV7pzFiI$~t4QN;vEC}X4n z7RxDpAOV!j*w8ni4MAK3S~6v&;)g`l$axh<$7|>E5RD*h?RH*K2Y`j8L7%1v@%vZi za7@bt@uOUvisvQJuXPqpaHQCkREqd6M>0WG?6AwXR*T65ziuw$&~q$MS$o zfPyh>s<0l}mI@eh_hd(oB8*1tHZ@ojWl%QM;T+Jdm>k66jW?rZ#Atx!qns4-g&E4v z(=;FQ%W^avW?3J{L@2IeV>_(Ca)Lk1vm70uX*$9Rewm8!AxRF0BcZTNSFka?U@5u^ zDtpMY2lVtCmQm<8@|YxHuf`Qs(;a!QQ=g4=WngL}AQLr> z9JWrdsBIHKHXF!fSydodRsaOc@jgNkSU^x9kY&;UP<}3pZ{joC5f_Tevd>4eG~;)Y z=eZ~qp=5#aaUn*E3OES^BApKTU&mCAU>iEyt^S9?)&v0^j*SWDqjRZr20>6rTPSJ& zlzz0f);`}+^~w}lP1PK7Ew3f7ot#*uJ@>1Yo3J0TdsRKpA+*n9JnDXDrM~YvF`;uS|vAh|-QdmRf4AqG=`U z#v1n_Lxg8;&z#YCU2K`_W{-A zUf_|V)B9U(WZ~PP>)O(JZ|Vc-*qP&Q{c~BE~6izDPQq)#Nu*KOf(n^(VHY9;fiINM65``pc+9*v(mL$bwfCjbc%v9V{8r9iX|O%>Nr%pLD2qT{mty}c=LVleeamv znz3SOSm@kP8jThvOOq(56Yzh*fz(booe!uZij=BJC6+_lbvQ~B8nA2>kXdv_RDtRY z`5QXWWEySCe6vbTs^#f?J!WC*{1~RgVx!nJTJjQyO{dRANgx|FnymtGbD9%JmCh9^y)##j7{Dcqfn*1ta$rG89pJF6w-S7Z037$rr|y0;1Onp_ zGFJdT6Q!1C0AdVB0WOmpuV=AgAQ550Tn+-mivTtYPJmz*#75#_n9oV%!#rSOfmAfy zki%C~=fTp1{O#BLpJ|0jj#m6#|LRWit-vq3PE1z9ZqyvET4sX$-Icqy7t z<=aq5ff86AuBZBu6EjJsYWM0uejufWFTwPA7Su}0Bm$7KFb!q{Um_8~A{LUG#1l(l zSehUda@kU8LIRg9fkk2tZ;~ss5~R+mM<==F7hLHpxqLB>>PQS%Vc7b~?q!%T5+h8Q z4G=4Nzyi5WZ?^gkasJ{?Xhm`JC#WG6$1K2jb@=9&D3EgD#3UhGh#*21rJjulVXjCF zvp76q62jt0zzMG5C7DlfMgPl%C^3+~wf|}Lq=}jz|MmIcQjh1Ok6NjD$Em^Iv26D> z8tt_TnM9~^Tt8mflRGPOrrX|HtT3gG4LEuuk{g2Rn}QgJIa?gZo))!!=o_l9bvD%A zZ`aHajl8#~u?!4f7F#*b*->A=R2L)6!>saz?h>#wTXT-I(XmQ zx{84skS>k=i~i`(6k4C7;Zpfx%dCPVjPayMf8pugtGM=~s=Id1l#8MZJ1-73wV#Q3 zR3>v3%}jbQs1f_Z0xo;%=LILlA+nTpKI4ha%xWW}uqHrNao~&T4AY6m`P$_n-6h*g zhoX+e4n%~gl_lhe#s+AMb7d{5WzvYTa%6Q~si@@4{;s(0zU|H&P3fE+t{7X`S#Cj@ zC#vd}^4pcBD*77Ny5=j$h8EL2_t$O38$SQiJ6fPjJMimypr~MB2(&P0aI|h}$64<0 z>_~duqNjaT=DM^6+N{&B_lED;F2wrl?!4Lk*2((x!fmrcsw+=cI^qttuZ9C}-m~5E z-ryYVpL%^xR#&(0YI5hz<(}F7-p)?FPcyJO-zVO>%9ZDXJH8pnY;GJYFDQ>vd#j_* zRrd}L(r=!g+1#nQwsO?kpS`Qq8`NxE+Zy{gf7*_7J*U2V_|NpLo{iasj7VCg_V9&| ShohtYzipXxh2)4xTk + + + Keychain Reference + + + + + + + + + +
+
+

Keychain Docs (100% documented)

+
+
+
+ +
+
+ +
+
+
+ +

Overview

+ +
+

Supports iOS only.

+
+ +

Keychain is a wrapper library built around a small subset of features offered by Keychain Services to simplify saving and retrieving data to and from the iOS Keychain using kSecClassGenericPassword class.

+ +

While the Keychain Services offer comprehensive set of APIs and could be used directly, the app-side implementation for saving and retrieving data will most likely be verbose.

+ +

In a nutshell, to securely store an item using Keychain Services, a dictionary of predefined keys and values, also referred to as the keychain query, must be created first. This query must contain valid values for predefined set of keys that depend on a security class being used. To reduce the amount of manual work required to create a keychain query, this framework takes advantage of Swift features such as default implementation for protocols, generics and Codable for automatic encoding of models into external representation.

+ +

This approach leads to a much cleaner interaction with iOS Keychain that’s enjoyable to use.

+

Features

+ +
    +
  • [x] Simple to setup, easy to use & efficient
  • +
  • [x] Supports custom data types
  • +
  • [x] Supports storing multiple instances of the same type
  • +
  • [x] Supports app and group-specific keychain configurations
  • +
  • [x] Handles object encoding and decoding from data returned by the iOS keychain
  • +
  • [x] Comprehensive Unit Test Coverage
  • +
  • [x] Complete Documentation
  • +
+

Requirements

+ +
    +
  • iOS 10.0+
  • +
  • Xcode 9.0+
  • +
  • Swift 4.0+
  • +
+

Installation

+ +

Carthage is the only supported way to install Keychain framework.

+
github "AlaskaAirlines/Keychain" ~> 1.0.0
+
+ +

For more information on getting started with Carthage, visit the repo.

+

Usage

+ +

Keychain framework currently supports two access types - App Specific and Group Specific. The iCloud sync support across multiple devices will be added later.

+ +

Getting started is easy. First, create the keychain instance using one of the supported access types.

+
let keychain = Keychain(access: .appSpecific(serviceName: "App"))
+
+ +

Any custom type you want to encrypt and store in iOS Keychain needs to conform and implement the KeychainItem protocol. The KeychainItem protocol provides default implementation for all of its properties - except the idKey. See documentation for more information.

+
struct User: KeychainItem {
+    let username: String
+    let password: String
+
+    // MARK: KeychainItem
+
+    var idKey: String {
+        return username
+    }
+}
+
+ +

Keychain offers a handful of methods that will allow you to save, delete, or retrieve items.

+
let user = User(username: "username", password: "password")
+
+// save
+try? keychain.save(user)
+
+// retrieve users
+let users = try? keychain.items(ofType: User.self)
+
+// retrieve a single user
+let user = try? keychain.item(ofType: User.self, idKey: "username")
+
+ +

For group specific configuration, please see documentation.

+

Performance

+ +

The following tests were performed on an iPad Mini 4 WiFi + Cellular. The numbers are the average for performing each operation 3000 times.

+ +
    +
  • Deleting: 0.00662
  • +
  • Inserting: 0.00862
  • +
  • Reading: 0.00291
  • +
  • Replacing: 0.00858
  • +
+

Communication

+ +
    +
  • If you found a bug, open an issue.
  • +
  • If you have a feature request, open an issue.
  • +
  • If you want to contribute, submit a pull request.
  • +
+

Authors

+ + +

Contributors

+ + + +
+
+ +
+
+ + + diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/js/jazzy.js b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/js/jazzy.js new file mode 100755 index 0000000..3965b5f --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/js/jazzy.js @@ -0,0 +1,46 @@ +window.jazzy = {'docset': false} +if (typeof window.dash != 'undefined') { + document.documentElement.className += ' dash' + window.jazzy.docset = true +} +if (navigator.userAgent.match(/xcode/i)) { + document.documentElement.className += ' xcode' + window.jazzy.docset = true +} + +// On doc load, toggle the URL hash discussion if present +$(document).ready(function() { + if (!window.jazzy.docset) { + var linkToHash = $('a[href="' + window.location.hash +'"]'); + linkToHash.trigger("click"); + } +}); + +// On token click, toggle its discussion and animate token.marginLeft +$(".token").click(function(event) { + if (window.jazzy.docset) { + return; + } + var link = $(this); + var animationDuration = 300; + var tokenOffset = "15px"; + var original = link.css('marginLeft') == tokenOffset; + link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration); + $content = link.parent().parent().next(); + $content.slideToggle(animationDuration); + + // Keeps the document from jumping to the hash. + var href = $(this).attr('href'); + if (history.pushState) { + history.pushState({}, '', href); + } else { + location.hash = href; + } + event.preventDefault(); +}); + +// Dumb down quotes within code blocks that delimit strings instead of quotations +// https://github.com/realm/jazzy/issues/714 +$("code q").replaceWith(function () { + return ["\"", $(this).contents(), "\""]; +}); diff --git a/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/js/jquery.min.js b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/js/jquery.min.js new file mode 100755 index 0000000..ab28a24 --- /dev/null +++ b/Documentation/docsets/Keychain.docset/Contents/Resources/Documents/js/jquery.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h; +if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="
a",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:k.htmlSerialize?[0,"",""]:[1,"X
","
"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("