[
  {
    "path": ".github/FUNDING.yml",
    "content": "tidelift: \"cocoapods/PromiseKit\"\npatreon: \"mxcl\"\ngithub: mxcl\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "[PLEASE READ THE TROUBLESHOOTING GUIDE](https://github.com/mxcl/PromiseKit/blob/master/Documentation/Troubleshooting.md).\n\n---\n\nYou read the guide but it didn’t help? OK, we’re here to help.\n\n* Please specify the PromiseKit major version you are using\n* [Please format your code in triple backticks and ensure readable indentation](https://help.github.com/articles/creating-and-highlighting-code-blocks/)\n* Please specify how you installed PromiseKit, ie. Carthage, CocoaPods, SwiftPM or other. If other provide DETAILED information about how you are integrating PromiseKit.\n\nIf you ignore this template we will close your ticket and link to this template until you provide this necessary information. We cannot help you without it.\n"
  },
  {
    "path": ".github/LinuxMain.stencil",
    "content": "@testable import Core\n@testable import A_\nimport XCTest\n\n//TODO get this to run on CI and don’t have it committed\n//NOTE problem is Sourcery doesn’t support Linux currently\n//USAGE: cd PromiseKit/Sources/.. && sourcery --config .github/sourcery.yml\n\n{% for type in types.classes|based:\"XCTestCase\" %}\nextension {{ type.name }} {\n    static var allTests = [\n    {% for method in type.methods %}{% if method.parameters.count == 0 and method.shortName|hasPrefix:\"test\" %}    (\"{{ method.shortName }}\", {{type.name}}.{{ method.shortName }}),\n    {% endif %}{% endfor %}]\n}\n\n{% endfor %}\nXCTMain([\n{% for type in types.classes|based:\"XCTestCase\" %}{% if not type.annotations.excludeFromLinuxMain %}    testCase({{ type.name }}.allTests),\n{% endif %}{% endfor %}])\n"
  },
  {
    "path": ".github/codecov.yml",
    "content": "ignore:\n  - \"Tests\"\n  - \"README.md\"\n  - \"Documentation\"\n  - \".travis.yml\"\n\ncodecov:\n  notify:\n    require_ci_to_pass: yes\n\ncoverage:\n  precision: 1\n  round: up\n  range: \"70...100\"\n\n  status:\n    project: yes\n    patch:\n      default:\n        threshold: 0.2%\n    changes: no\n\nparsers:\n  gcov:\n    branch_detection:\n      conditional: yes\n      loop: yes\n      method: no\n      macro: no\n\ncomment: off\n"
  },
  {
    "path": ".github/jazzy.yml",
    "content": "module: PromiseKit\ncustom_categories:\n  - name: Core Components\n    children:\n      - Promise\n      - Guarantee\n      - Thenable\n      - CatchMixin\n      - Resolver\nxcodebuild_arguments:\n  - UseModernBuildSystem=NO\noutput:\n  ../output\n  # output directory is relative to config file… ugh\nreadme:\n  Documentation/README.md\ntheme:\n  fullwidth\n"
  },
  {
    "path": ".github/ranger.yml",
    "content": "merges:\n  - action: delete_branch\n"
  },
  {
    "path": ".github/sourcery.yml",
    "content": "sources:\n  include:\n    - ../Tests/A+\n    - ../Tests/CorePromise\n  exclude:\n    - ../Tests/A+/0.0.0.swift\n    - ../Tests/CorePromise/Utilities.swift\ntemplates:\n  include:\n    - LinuxMain.stencil\noutput:\n  ../Tests/LinuxMain.swift\n"
  },
  {
    "path": ".github/workflows/cd.yml",
    "content": "name: CD\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        required: true\njobs:\n  pods:\n    runs-on: macos-latest\n    steps:\n\n    - name: Start Deployment\n      uses: bobheadxi/deployments@v0.5.2\n      id: deployment\n      with:\n        step: start\n        token: ${{ secrets.GITHUB_TOKEN }}\n        env: pods\n\n    - uses: actions/checkout@v3\n      with:\n        submodules: true\n\n    - run: pod trunk push --allow-warnings --skip-tests --skip-import-validation\n      env:\n        COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}\n\n    - name: Seal Deployment\n      uses: bobheadxi/deployments@v0.5.2\n      if: always()\n      with:\n        step: finish\n        token: ${{ secrets.GITHUB_TOKEN }}\n        status: ${{ job.status }}\n        deployment_id: ${{ steps.deployment.outputs.deployment_id }}\n\n  # carthage:\n  #   runs-on: macos-latest\n  #   steps:\n\n  #   - name: Start Deployment\n  #     uses: bobheadxi/deployments@v0.5.2\n  #     id: deployment\n  #     with:\n  #       step: start\n  #       token: ${{ secrets.GITHUB_TOKEN }}\n  #       env: carthage\n\n  #   - uses: maxim-lobanov/setup-xcode@v1\n  #     with:\n  #       xcode-version: ^11\n  #       # Waiting on https://github.com/Carthage/Carthage/issues/3103 for Xcode 12\n\n  #   - uses: joutvhu/get-release@v1\n  #     id: release\n  #     with:\n  #       tag_name: ${{ github.event.inputs.version }}\n  #     env:\n  #       GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n  #   - uses: actions/checkout@v2\n  #   - run: carthage build --no-skip-current --platform macOS,iOS,watchOS,tvOS --archive\n  #   - run: mv PromiseKit.framework.zip PromiseKit-$v.framework.zip\n\n  #   - uses: actions/upload-release-asset@v1\n  #     with:\n  #       upload_url: ${{ steps.release.outputs.upload_url }}\n  #       asset_path: ./PromiseKit-${{ github.event.inputs.version }}.framework.zip\n  #       asset_name: PromiseKit-${{ github.event.inputs.version }}.framework.zip\n  #       asset_content_type: application/zip\n  #     env:\n  #       GITHUB_TOKEN: ${{ github.token }}\n\n  #   - name: Seal Deployment\n  #     uses: bobheadxi/deployments@v0.5.2\n  #     if: always()\n  #     with:\n  #       step: finish\n  #       token: ${{ secrets.GITHUB_TOKEN }}\n  #       status: ${{ job.status }}\n  #       deployment_id: ${{ steps.deployment.outputs.deployment_id }}\n\n  docs:\n    runs-on: macos-latest\n    steps:\n\n    - name: Start Deployment\n      uses: bobheadxi/deployments@v0.5.2\n      id: deployment\n      with:\n        step: start\n        token: ${{ secrets.GITHUB_TOKEN }}\n        env: docs\n\n    - uses: actions/checkout@v2\n    - run: gem install jazzy\n    - run: |\n        jazzy --config .github/jazzy.yml \\\n          --github_url 'https://github.com/mxcl/PromiseKit' \\\n          --module-version ${{ github.event.inputs.version }}\n    - run: git remote update\n    - run: git checkout gh-pages\n    - run: rm -rf reference/v6\n    - run: mv output reference/v6\n    - run: git add reference/v6\n    - run: git config user.name github-actions\n    - run: git config user.email github-actions@github.com\n    - run: git commit -m 'Updated docs for v${{ github.event.inputs.version }}'\n    - run: git remote add secure-origin https://${{ secrets.JAZZY_PAT }}@github.com/mxcl/PromiseKit.git\n    - run: git push secure-origin gh-pages\n\n    - name: Seal Deployment\n      uses: bobheadxi/deployments@v0.5.2\n      if: always()\n      with:\n        step: finish\n        token: ${{ secrets.GITHUB_TOKEN }}\n        status: ${{ job.status }}\n        deployment_id: ${{ steps.deployment.outputs.deployment_id }}\n"
  },
  {
    "path": ".github/workflows/ci-podspec.yml",
    "content": "on:\n  workflow_dispatch:\n  pull_request:\n    paths:\n      - PromiseKit.podspec\njobs:\n  lint:\n    runs-on: macos-15\n    steps:\n    - uses: maxim-lobanov/setup-xcode@v1\n      with:\n        xcode-version: 16\n    - uses: maxim-lobanov/setup-cocoapods@v1\n      with:\n        version: 1.16.2\n    - uses: actions/checkout@v2\n      with:\n        submodules: true\n    - run: pod lib lint --fail-fast --allow-warnings\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non:\n  workflow_dispatch:\n  workflow_call:\n  pull_request:\n    paths:\n      - Sources/**\n      - Tests/**\n      - .github/workflows/ci.yml\n      - PromiseKit.xcodeproj/**\n\nconcurrency:\n  group: ${{ github.ref }}\n  cancel-in-progress: true\n\njobs:\n  linux-build:\n    name: Linux (Swift ${{ matrix.swift }})\n    runs-on: ubuntu-22.04\n    strategy:\n      matrix:\n        swift:\n        - '4.0'\n        - '4.1'\n        - '4.2'\n    container:\n      image: swift:${{ matrix.swift }}\n    steps:\n    - uses: actions/checkout@v1 # DO NOT UPDATE ∵ failure on older containers due to old glibc\n    - run: swift build -Xswiftc -warnings-as-errors -Xswiftc -swift-version -Xswiftc 3\n    - run: swift build  # can’t test ∵ generated linuxmain requires Swift 5\n\n  linux-test:\n    name: Linux (Swift ${{ matrix.swift }})\n    runs-on: ubuntu-latest\n    continue-on-error: true\n    strategy:\n      matrix:\n        swift:\n        - '5.0'\n        - '5.1'\n        - '5.2'\n        - '5.3'\n        - '5.4'\n        - '5.5'\n        - '5.6'\n        - '5.7'\n        - '5.8'\n        - '5.9'\n        - '5.10'\n        - '6.0'\n    container:\n      image: swift:${{ matrix.swift }}\n    steps:\n    - uses: actions/checkout@v1 # DO NOT UPDATE ∵ failure on older containers due to old glibc\n    - run: swift build -Xswiftc -warnings-as-errors -Xswiftc -swift-version -Xswiftc 4\n      if: ${{ matrix.swift < 6 }}\n    - run: swift build -Xswiftc -warnings-as-errors -Xswiftc -swift-version -Xswiftc 4.2\n      if: ${{ matrix.swift < 6 }}\n    - run: swift test --enable-code-coverage --parallel\n\n    - name: Generate Coverage Report\n      if: ${{ matrix.swift >= 6 }}\n      run: |\n        apt-get -qq update\n        apt-get -qq install llvm-18 curl\n        export b=$(swift build --show-bin-path) && llvm-cov-18 \\\n          export -format lcov \\\n          -instr-profile=$b/codecov/default.profdata \\\n          --ignore-filename-regex='\\.build/' \\\n          $b/*.xctest \\\n          > info.lcov\n\n    - uses: codecov/codecov-action@v1\n      with:\n        file: ./info.lcov\n      if: ${{ matrix.swift >= 6 }}\n\n  test:\n    runs-on: macos-latest\n    name: ${{ matrix.platform }}\n    continue-on-error: true\n    strategy:\n      matrix:\n        platform:\n          - macOS\n          - watchOS\n          - tvOS\n          - iOS\n          # - mac-catalyst\n          # - visionOS\n          # ^^ both are unavailable in the github-hosted runners\n    steps:\n    - uses: actions/checkout@v4\n    - uses: mxcl/xcodebuild@v3\n      with:\n        platform: ${{ matrix.platform }}\n        code-coverage: true\n    - uses: codecov/codecov-action@v1\n\n  test-android:\n    name: Android\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v4\n    - uses: skiptools/swift-android-action@v2\n"
  },
  {
    "path": ".github/workflows/publish.yml",
    "content": "name: Publish\n\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        description: semantic version to publish\n        required: true\n\nconcurrency:\n  group: publish-{{github.event.inputs.version}}\n  cancel-in-progress: true\n\njobs:\n  ci:\n    uses: ./.github/workflows/ci.yml\n\n  lint:\n    runs-on: macos-latest\n    strategy:\n      matrix:\n        xcode:\n          - ^16\n    steps:\n    - uses: maxim-lobanov/setup-xcode@v1\n      with:\n        xcode-version: ${{ matrix.xcode }}\n    - uses: actions/checkout@v3\n      with:\n        submodules: true\n    - run: pod lib lint --fail-fast --allow-warnings\n\n  create-release:\n    runs-on: ubuntu-latest\n    needs: [ci, lint]\n    env:\n      v: ${{ github.event.inputs.version }}\n    steps:\n    - uses: actions/checkout@v3\n      with:\n        fetch-depth: 0  # zero means “all” (or push fails)\n    - name: Update committed versions\n      run: |\n        ruby -i -pe \"sub(/CURRENT_PROJECT_VERSION = [0-9.]+/, 'CURRENT_PROJECT_VERSION = $v')\" PromiseKit.xcodeproj/project.pbxproj\n        ruby -i -pe \"sub(/s.version = '[0-9.]+'/, 's.version = \\'$v\\'')\" PromiseKit.podspec\n    - run: |\n        ! (git diff --quiet)\n    - name: Commit\n      run: |\n        git config user.name github-actions\n        git config user.email github-actions@github.com\n        git commit -am \"PromiseKit $v\"\n        git push\n    - uses: softprops/action-gh-release@v1\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      with:\n        tag_name: ${{ github.event.inputs.version }}\n        name: ${{ github.event.inputs.version }}\n\n  cd:\n    needs: create-release\n    runs-on: ubuntu-latest\n    steps:\n    - uses: aurelien-baudet/workflow-dispatch@v2\n      with:\n        workflow: CD\n        token: ${{ secrets.JAZZY_PAT }}\n        inputs: \"{\\\"version\\\": \\\"${{ github.event.inputs.version }}\\\"}\"\n        ref: ${{ env.GITHUB_REF_NAME }}  # or uses the SHA rather than branch and thus the above commit is not used\n        wait-for-completion: true\n"
  },
  {
    "path": ".gitignore",
    "content": "*.xcodeproj/**/xcuserdata/\n*.xcscmblueprint\n/Carthage\n/.build\n.DS_Store\nDerivedData\n/Extensions/Carthage\n/Tests/JS-A+/build\n.swiftpm/\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"Extensions/Foundation\"]\n\tpath = Extensions/Foundation\n\turl = https://github.com/PromiseKit/Foundation.git\n[submodule \"Extensions/UIKit\"]\n\tpath = Extensions/UIKit\n\turl = https://github.com/PromiseKit/UIKit.git\n[submodule \"Extensions/Accounts\"]\n\tpath = Extensions/Accounts\n\turl = https://github.com/PromiseKit/Accounts.git\n[submodule \"Extensions/MessagesUI\"]\n\tpath = Extensions/MessagesUI\n\turl = https://github.com/PromiseKit/MessagesUI.git\n[submodule \"Extensions/WatchConnectivity\"]\n\tpath = Extensions/WatchConnectivity\n\turl = https://github.com/PromiseKit/WatchConnectivity.git\n[submodule \"Extensions/Photos\"]\n\tpath = Extensions/Photos\n\turl = https://github.com/PromiseKit/Photos.git\n[submodule \"Extensions/MapKit\"]\n\tpath = Extensions/MapKit\n\turl = https://github.com/PromiseKit/MapKit.git\n[submodule \"Extensions/CloudKit\"]\n\tpath = Extensions/CloudKit\n\turl = https://github.com/PromiseKit/CloudKit.git\n[submodule \"Extensions/AddressBook\"]\n\tpath = Extensions/AddressBook\n\turl = https://github.com/PromiseKit/AddressBook.git\n[submodule \"Extensions/AssetsLibrary\"]\n\tpath = Extensions/AssetsLibrary\n\turl = https://github.com/PromiseKit/AssetsLibrary.git\n[submodule \"Extensions/CoreLocation\"]\n\tpath = Extensions/CoreLocation\n\turl = https://github.com/PromiseKit/CoreLocation.git\n[submodule \"Extensions/QuartzCore\"]\n\tpath = Extensions/QuartzCore\n\turl = https://github.com/PromiseKit/QuartzCore.git\n[submodule \"Extensions/Social\"]\n\tpath = Extensions/Social\n\turl = https://github.com/PromiseKit/Social.git\n[submodule \"Extensions/StoreKit\"]\n\tpath = Extensions/StoreKit\n\turl = https://github.com/PromiseKit/StoreKit.git\n[submodule \"Extensions/Bolts\"]\n\tpath = Extensions/Bolts\n\turl = https://github.com/PromiseKit/Bolts.git\n[submodule \"Extensions/CoreBluetooth\"]\n\tpath = Extensions/CoreBluetooth\n\turl = https://github.com/PromiseKit/CoreBluetooth.git\n[submodule \"Extensions/EventKit\"]\n\tpath = Extensions/EventKit\n\turl = https://github.com/PromiseKit/EventKit.git\n[submodule \"Extensions/SystemConfiguration\"]\n\tpath = Extensions/SystemConfiguration\n\turl = https://github.com/PromiseKit/SystemConfiguration\n[submodule \"Extensions/Alamofire\"]\n\tpath = Extensions/Alamofire\n\turl = https://github.com/PromiseKit/Alamofire\n[submodule \"Extensions/OMGHTTPURLRQ\"]\n\tpath = Extensions/OMGHTTPURLRQ\n\turl = https://github.com/PromiseKit/OMGHTTPURLRQ\n[submodule \"Extensions/AVFoundation\"]\n\tpath = Extensions/AVFoundation\n\turl = https://github.com/PromiseKit/AVFoundation\n[submodule \"Extensions/HomeKit\"]\n\tpath = Extensions/HomeKit\n\turl = https://github.com/PromiseKit/HomeKit.git\n[submodule \"Extensions/HealthKit\"]\n\tpath = Extensions/HealthKit\n\turl = https://github.com/PromiseKit/PMKHealthKit\n"
  },
  {
    "path": ".tidelift.yml",
    "content": "extra_ignore_directories: [ Tests ]\n"
  },
  {
    "path": ".travis.yml",
    "content": "os: osx\nlanguage: swift\nosx_image: xcode9.4\n\nif: tag =~ /^[0-9]+\\.[0-9]+\\.[0-9]+/\n\nstages:\n  - swiftpm\n  - carthage\n\njobs:\n  include:\n    - &swiftpm\n      stage: swiftpm\n      osx_image: xcode9.4\n      script: swift build\n    - <<: *swiftpm\n      osx_image: xcode10.3\n    - <<: *swiftpm\n      osx_image: xcode11.6\n\n    - &carthage\n      stage: carthage\n      osx_image: xcode9.4\n      install: sed -i '' \"s/SWIFT_TREAT_WARNINGS_AS_ERRORS = NO;/SWIFT_TREAT_WARNINGS_AS_ERRORS = YES;/\" *.xcodeproj/project.pbxproj\n      script: carthage build --no-skip-current\n    - <<: *carthage\n      osx_image: xcode10.3\n    - <<: *carthage\n      osx_image: xcode11.6\n"
  },
  {
    "path": "Documentation/Appendix.md",
    "content": "# Common Misusage\n\n## Doubling up Promises\n\nDon’t do this:\n\n```swift\nfunc toggleNetworkSpinnerWithPromise<T>(funcToCall: () -> Promise<T>) -> Promise<T> {\n    return Promise { seal in\n        firstly {\n            setNetworkActivityIndicatorVisible(true)\n            return funcToCall()\n        }.then { result in\n            seal.fulfill(result)\n        }.always {\n            setNetworkActivityIndicatorVisible(false)\n        }.catch { err in\n            seal.reject(err)\n        }\n    }\n}\n```\n\nDo this:\n\n```swift\nfunc toggleNetworkSpinnerWithPromise<T>(funcToCall: () -> Promise<T>) -> Promise<T> {\n    return firstly {\n        setNetworkActivityIndicatorVisible(true)\n        return funcToCall()\n    }.always {\n        setNetworkActivityIndicatorVisible(false)\n    }\n}\n```\n\nYou already *had* a promise, you don’t need to wrap it in another promise.\n\n\n## Optionals in Promises\n\nWhen we see `Promise<Item?>`, it usually implies a misuse of promises. For\nexample:\n\n```swift\nreturn firstly {\n    getItems()\n}.then { items -> Promise<[Item]?> in\n    guard !items.isEmpty else {\n        return .value(nil)\n    }\n    return Promise(value: items)\n}\n```\n\nThe second `then` chooses to return `nil` in some circumstances. This choice\nimposes the need to check for `nil` on the consumer of the promise.\n\nIt's usually better to shunt these sorts of exceptions away from the\nhappy path and onto the error path. In this case, we can create a specific\nerror type for this condition:\n\n```swift\nreturn firstly {\n    getItems()\n}.map { items -> [Item]> in\n    guard !items.isEmpty else {\n        throw MyError.emptyItems\n    }\n    return items\n}\n```\n\n> *Note*: Use `compactMap` when an API outside your control returns an Optional and you want to generate an error instead of propagating `nil`.\n\n# Tips n’ Tricks\n\n## Background-Loaded Member Variables\n\n```swift\nclass MyViewController: UIViewController {\n    private let ambience: Promise<AVAudioPlayer> = DispatchQueue.global().async(.promise) {\n        guard let asset = NSDataAsset(name: \"CreepyPad\") else { throw PMKError.badInput }\n        let player =  try AVAudioPlayer(data: asset.data)\n        player.prepareToPlay()\n        return player\n    }\n}\n```\n\n## Chaining Animations\n\n```swift\nfirstly {\n    UIView.animate(.promise, duration: 0.3) {\n        self.button1.alpha = 0\n    }\n}.then {\n    UIView.animate(.promise, duration: 0.3) {\n        self.button2.alpha = 1\n    }\n}.then {\n    UIView.animate(.promise, duration: 0.3) {\n        adjustConstraints()\n        self.view.layoutIfNeeded()\n    }\n}\n```\n\n\n## Voiding Promises\n\nIt is often convenient to erase the type of a promise to facilitate chaining.\nFor example, `UIView.animate(.promise)` returns `Guarantee<Bool>` because UIKit’s\ncompletion API supplies a `Bool`. However, we usually don’t need this value and \ncan chain more simply if it is discarded (that is, converted to `Void`). We can use\n`asVoid()` to achieve this conversion:\n\n```swift\nUIView.animate(.promise, duration: 0.3) {\n    self.button1.alpha = 0\n}.asVoid().done(self.nextStep)\n```\n\nFor situations in which we are combining many promises into a `when`, `asVoid()`\nbecomes essential:\n\n```swift\nlet p1 = foo()\nlet p2 = bar()\nlet p3 = baz()\n//…\nlet p10 = fluff()\n\nwhen(fulfilled: p1.asVoid(), p2.asVoid(), /*…*/, p10.asVoid()).then {\n    let value1 = p1.value!  // safe bang since all the promises fulfilled\n    // …\n    let value10 = p10.value!\n}.catch {\n    //…\n}\n```\n\nYou normally don't have to do this explicitly because `when` does it for you\nfor up to 5 parameters.\n\n\n## Blocking (Await)\n\nSometimes you have to block the main thread to await completion of an asynchronous task.\nIn these cases, you can (with caution) use `wait`:\n\n```swift\npublic extension UNUserNotificationCenter {\n    var wasPushRequested: Bool {\n        let settings = Guarantee(resolver: getNotificationSettings).wait()\n        return settings != .notDetermined\n    }\n}\n```\n\nThe task under the promise **must not** call back onto the current thread or it\nwill deadlock.\n\n## Starting a Chain on a Background Queue/Thread\n\n`firstly` deliberately does not take a queue. A detailed rationale for this choice\ncan be found in the ticket tracker.\n\nSo, if you want to start a chain by dispatching to the background, you have to use\n`DispatchQueue.async`:\n\n```swift\nDispatchQueue.global().async(.promise) {\n    return value  \n}.done { value in\n    //…\n}\n```\n\nHowever, this function cannot return a promise because of Swift compiler ambiguity\nissues. Thus, if you must start a promise on a background queue, you need to\ndo something like this:\n\n\n```swift\nPromise { seal in\n    DispatchQueue.global().async {\n        seal(value)\n    }  \n}.done { value in\n    //…\n}\n```\n\nOr more simply (though with caveats; see the documentation for `wait`):\n\n```swift\nDispatchQueue.global().async(.promise) {\n    return try fetch().wait()\n}.done { value in\n    //…\n}\n```\n\nHowever, you shouldn't need to do this often. If you find yourself wanting to use\nthis technique, perhaps you should instead modify the code for `fetch` to make it do\nits work on a background thread.\n\nPromises abstract asynchronicity, so exploit and support that model. Design your\nAPIs so that consumers don’t have to care what queue your functions run on.\n"
  },
  {
    "path": "Documentation/CommonPatterns.md",
    "content": "# Common Patterns\n\nOne feature of promises that makes them particularly useful is that they are composable.\nThis fact enables complex, yet safe asynchronous patterns that would otherwise be quite\nintimidating when implemented with traditional methods.\n\n\n## Chaining\n\nThe most common pattern is chaining:\n\n```swift\nfirstly {\n    fetch()\n}.then {\n    map($0)\n}.then {\n    set($0)\n    return animate()\n}.ensure {\n    // something that should happen whatever the outcome\n}.catch {\n    handle(error: $0)\n}\n```\n\nIf you return a promise in a `then`, the next `then` *waits* on that promise\nbefore continuing. This is the essence of promises.\n\nPromises are easy to compose, so they encourage you to develop highly asynchronous\napps without fear of the spaghetti code (and associated refactoring pains) of\nasynchronous systems that use completion handlers.\n\n\n## APIs That Use Promises\n\nPromises are composable, so return them instead of accepting completion blocks:\n\n```swift\nclass MyRestAPI {\n    func user() -> Promise<User> {\n        return firstly {\n            URLSession.shared.dataTask(.promise, with: url)\n        }.compactMap {\n            try JSONSerialization.jsonObject(with: $0.data) as? [String: Any]\n        }.map { dict in\n            User(dict: dict)\n        }\n    }\n\n    func avatar() -> Promise<UIImage> {\n        return user().then { user in\n            URLSession.shared.dataTask(.promise, with: user.imageUrl)\n        }.compactMap {\n            UIImage(data: $0.data)\n        }\n    }\n}\n```\n\nThis way, asynchronous chains can cleanly and seamlessly incorporate code from all over\nyour app without violating architectural boundaries.\n\n> *Note*: We provide [promises for Alamofire](https://github.com/PromiseKit/Alamofire-) too!\n\n\n## Background Work\n\n```swift\nclass MyRestAPI {\n    func avatar() -> Promise<UIImage> {\n        let bgq = DispatchQueue.global(qos: .userInitiated)\n\n        return firstly {\n            user()\n        }.then(on: bgq) { user in\n            URLSession.shared.dataTask(.promise, with: user.imageUrl)\n        }.compactMap(on: bgq) {\n            UIImage(data: $0)\n        }\n    }\n}\n```\n\nAll PromiseKit handlers take an `on` parameter that lets you designate the dispatch queue\non which to run the handler. The default is always the main queue.\n\nPromiseKit is *entirely* thread safe.\n\n> *Tip*: With caution, you can have all `then`, `map`, `compactMap`, etc., run on\na background queue. See `PromiseKit.conf`. Note that we suggest only changing\nthe queue for the `map` suite of functions, so `done` and `catch` will\ncontinue to run on the main queue, which is *usually* what you want.\n\n## Failing Chains\n\nIf an error occurs mid-chain, simply throw an error:\n\n```swift\nfirstly {\n    foo()\n}.then { baz in\n    bar(baz)\n}.then { result in\n    guard !result.isBad else { throw MyError.myIssue }\n    //…\n    return doOtherThing()\n}\n```\n\nThe error will surface at the next `catch` handler.\n\nSince promises handle thrown errors, you don't have to wrap calls to throwing functions \nin a `do` block unless you really want to handle the errors locally:\n\n```swift\nfoo().then { baz in\n    bar(baz)\n}.then { result in\n    try doOtherThing()\n}.catch { error in\n    // if doOtherThing() throws, we end up here\n}\n```\n\n> *Tip*: Swift lets you define an inline `enum Error` inside the function you\nare working on. This isn’t *great* coding practice, but it's better than\navoiding throwing an error because you couldn't be bothered to define a good global\n`Error` `enum`.\n\n\n## Abstracting Away Asynchronicity\n\n```swift\nvar fetch = API.fetch()\n\noverride func viewDidAppear() {\n    fetch.then { items in\n        //…\n    }\n}\n\nfunc buttonPressed() {\n    fetch.then { items in\n        //…\n    }\n}\n\nfunc refresh() -> Promise {\n    // ensure only one fetch operation happens at a time\n\n    if fetch.isResolved {\n        startSpinner()\n        fetch = API.fetch().ensure {\n            stopSpinner()\n        }\n    }\n    return fetch\n}\n```\n\nWith promises, you don’t need to worry about *when* your asynchronous operation\nfinishes. Just act like it already has.\n\nAbove, we see that you can call `then` as many times on a promise as you\nlike. All the blocks will be executed in the order they were added.\n\n\n## Chaining Sequences\n\nWhen you have a series of tasks to perform on an array of data:\n\n```swift\n// fade all visible table cells one by one in a “cascading” effect\n\nvar fade = Guarantee()\nfor cell in tableView.visibleCells {\n    fade = fade.then {\n        UIView.animate(.promise, duration: 0.1) {\n            cell.alpha = 0\n        }\n    }\n}\nfade.done {\n    // finish\n}\n```\n\nOr if you have an array of closures that return promises:\n\n```swift\nvar foo = Promise()\nfor nextPromise in arrayOfClosuresThatReturnPromises {\n    foo = foo.then(nextPromise)\n    // ^^ you rarely would want an array of promises instead, since then\n    // they have all already started, you may as well use `when()`\n}\nfoo.done {\n    // finish\n}\n```\n\n> *Note*: You *usually* want `when()`, since `when` executes all of its\ncomponent promises in parallel and so completes much faster. Use the pattern \nshown above in situations where tasks *must* be run sequentially; animation\nis a good example.\n\n> We also provide `when(concurrently:)`, which lets you schedule more than\none promise at a time if you need to.\n\n## Timeout\n\n```swift\nlet fetches: [Promise<T>] = makeFetches()\nlet timeout = after(seconds: 4)\n\nrace(when(fulfilled: fetches).asVoid(), timeout).then {\n    //…\n}\n```\n\n`race` continues as soon as one of the promises it is watching finishes.\n\nMake sure the promises you pass to `race` are all of the same type. The easiest way\nto ensure this is to use `asVoid()`.\n\nNote that if any component promise rejects, the `race` will reject, too.\n\n\n# Minimum Duration\n\nSometimes you need a task to take *at least* a certain amount of time. (For example,\nyou want to show a progress spinner, but if it shows for less than 0.3 seconds, the UI\nappears broken to the user.)\n\n```swift\nlet waitAtLeast = after(seconds: 0.3)\n\nfirstly {\n    foo()\n}.then {\n    waitAtLeast\n}.done {\n    //…\n}\n```\n\nThe code above works because we create the delay *before* we do work in `foo()`. By the \ntime we get to waiting on that promise, either it will have already timed out or we will wait\nfor whatever remains of the 0.3 seconds before continuing the chain.\n\n\n## Cancellation\n\nPromises don’t have a `cancel` function, but they do support cancellation through a\nspecial error type that conforms to the `CancellableError` protocol.\n\n```swift\nfunc foo() -> (Promise<Void>, cancel: () -> Void) {\n    let task = Task(…)\n    var cancelme = false\n\n    let promise = Promise<Void> { seal in\n        task.completion = { value in\n            guard !cancelme else { return reject(PMKError.cancelled) }\n            seal.fulfill(value)\n        }\n        task.start()\n    }\n\n    let cancel = {\n        cancelme = true\n        task.cancel()\n    }\n\n    return (promise, cancel)\n}\n```\n\nPromises don’t have a `cancel` function because you don’t want code outside of\nyour control to be able to cancel your operations--*unless*, of course, you explicitly\nwant to enable that behavior. In cases where you do want cancellation, the exact way \nthat it should work will vary depending on how the underlying task supports cancellation.\nPromiseKit provides cancellation primitives but no concrete API.\n\n**Important**: Errors which conform to the `CancellableError` protocol do *not* normally trigger the `.catch` block. \nCancelation is neither success nor failure, so cancelled chains do not call `catch` handlers by default. \nHowever you can intercept cancellation if you like:\n\n```swift\nfoo.then {\n    //…\n}.catch(policy: .allErrors) {\n    // cancelled errors are handled *as well*\n}\n```\n\n**Important**: Canceling a promise chain is *not* the same as canceling the underlying\nasynchronous task. Promises are wrappers around asynchronicity, but they have no\ncontrol over the underlying tasks. If you need to cancel an underlying task, you\nneed to cancel the underlying task!\n\n> The library [CancellablePromiseKit](https://github.com/johannesd/CancellablePromiseKit) extends the concept of Promises to fully cover cancellable tasks.\n\n## Retry / Polling\n\n```swift\nfunc attempt<T>(maximumRetryCount: Int = 3, delayBeforeRetry: DispatchTimeInterval = .seconds(2), _ body: @escaping () -> Promise<T>) -> Promise<T> {\n    var attempts = 0\n    func attempt() -> Promise<T> {\n        attempts += 1\n        return body().recover { error -> Promise<T> in\n            guard attempts < maximumRetryCount else { throw error }\n            return after(delayBeforeRetry).then(attempt)\n        }\n    }\n    return attempt()\n}\n\nattempt(maximumRetryCount: 3) {\n    flakeyTask(parameters: foo)\n}.then {\n    //…\n}.catch { _ in\n    // we attempted three times but still failed\n}\n```\n\nIn most cases, you should probably supplement the code above so that it re-attempts only for\nspecific error conditions.\n\n\n## Wrapping Delegate Systems\n\nBe careful with Promises and delegate systems, as they are not always compatible.\nPromises complete *once*, whereas most delegate systems may notify their delegate many\ntimes. This is why, for example, there is no PromiseKit extension for a\n`UIButton`.\n\nA good example of an appropriate time to wrap delegation is when you need a\nsingle `CLLocation` lookup:\n\n```swift\nextension CLLocationManager {\n    static func promise() -> Promise<CLLocation> {\n        return PMKCLLocationManagerProxy().promise\n    }\n}\n\nclass PMKCLLocationManagerProxy: NSObject, CLLocationManagerDelegate {\n    private let (promise, seal) = Promise<[CLLocation]>.pending()\n    private var retainCycle: PMKCLLocationManagerProxy?\n    private let manager = CLLocationManager()\n\n    init() {\n        super.init()\n        retainCycle = self\n        manager.delegate = self // does not retain hence the `retainCycle` property\n\n        promise.ensure {\n            // ensure we break the retain cycle\n            self.retainCycle = nil\n        }\n    }\n\n    @objc fileprivate func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) {\n        seal.fulfill(locations)\n    }\n\n    @objc func locationManager(_: CLLocationManager, didFailWithError error: Error) {\n        seal.reject(error)\n    }\n}\n\n// use:\n\nCLLocationManager.promise().then { locations in\n    //…\n}.catch { error in\n    //…\n}\n```\n\n> Please note: we provide this promise with our CoreLocation extensions at\n> https://github.com/PromiseKit/CoreLocation\n\n\n## Recovery\n\nSometimes you don’t want an error to cascade. Instead, you want to supply a default result:\n\n```swift\nCLLocationManager.requestLocation().recover { error -> Promise<CLLocation> in\n    guard error == MyError.airplaneMode else {\n        throw error\n    }\n    return .value(CLLocation.savannah)\n}.done { location in\n    //…\n}\n```\n\nBe careful not to ignore all errors, though! Recover only those errors that make sense to recover.\n\n\n## Promises for Modal View Controllers\n\n```swift\nclass ViewController: UIViewController {\n\n    private let (promise, seal) = Guarantee<…>.pending()  // use Promise if your flow can fail\n\n    func show(in: UIViewController) -> Promise<…> {\n        in.show(self, sender: in)\n        return promise\n    }\n\n    func done() {\n        dismiss(animated: true)\n        seal.fulfill(…)\n    }\n}\n\n// use:\n\nViewController().show(in: self).done {\n    //…\n}.catch { error in\n    //…\n}\n```\n\nThis is the best approach we have found, which is a pity as it requires the\npresentee to control the presentation and requires the presentee to dismiss itself\nexplicitly.\n\nNothing seems to beat storyboard segues for decoupling an app's controllers.\n\n\n## Saving Previous Results\n\nLet’s say you have:\n\n\n```swift\nlogin().then { username in\n    fetch(avatar: username)\n}.done { image in\n    //…\n}\n```\n\nWhat if you want access to both `username` and `image` in your `done`?\n\nThe most obvious way is to use nesting:\n\n```swift\nlogin().then { username in\n    fetch(avatar: username).done { image in\n        // we have access to both `image` and `username`\n    }\n}.done {\n    // the chain still continues as you'd expect\n}\n```\n\nHowever, such nesting reduces the clarity of the chain. Instead, we could use Swift\ntuples:\n\n```swift\nlogin().then { username in\n    fetch(avatar: username).map { ($0, username) }\n}.then { image, username in\n    //…\n}\n```\n\nThe code above simply maps `Promise<String>` into `Promise<(UIImage, String)>`.\n\n\n## Waiting on Multiple Promises, Whatever Their Result\n\nUse `when(resolved:)`:\n\n```swift\nwhen(resolved: a, b).done { (results: [Result<T>]) in\n    // `Result` is an enum of `.fulfilled` or `.rejected`\n}\n\n// ^^ cannot call `catch` as `when(resolved:)` returns a `Guarantee`\n```\n\nGenerally, you don't want this! People ask for it a lot, but usually because\nthey are trying to ignore errors. What they really need is to use `recover` on one of the\npromises. Errors happen, so they should be handled; you usually don't want to ignore them.\n"
  },
  {
    "path": "Documentation/Examples/ImageCache.md",
    "content": "# Image Cache with Promises\n\nHere is an example of a simple image cache that uses promises to simplify the\nstate machine:\n\n```swift\nimport Foundation\nimport PromiseKit\n\n/**\n * Small (10 images)\n * Thread-safe\n * Consolidates multiple requests to the same URLs\n * Removes stale entries (FIXME well, strictly we may delete while fetching from cache, but this is unlikely and non-fatal)\n * Completely _ignores_ server caching headers!\n */\n\nprivate let q = DispatchQueue(label: \"org.promisekit.cache.image\", attributes: .concurrent)\nprivate var active: [URL: Promise<Data>] = [:]\nprivate var cleanup = Promise()\n\n\npublic func fetch(image url: URL) -> Promise<Data> {\n    var promise: Promise<Data>?\n    q.sync {\n        promise = active[url]\n    }\n    if let promise = promise {\n        return promise\n    }\n\n    q.sync {\n        promise = Promise(.start) {\n\n            let dst = try url.cacheDestination()\n\n            guard !FileManager.default.isReadableFile(atPath: dst.path) else {\n                return Promise(dst)\n            }\n\n            return Promise { seal in\n                URLSession.shared.downloadTask(with: url) { tmpurl, _, error in\n                    do {\n                        guard let tmpurl = tmpurl else { throw error ?? E.unexpectedError }\n                        try FileManager.default.moveItem(at: tmpurl, to: dst)\n                        seal.fulfill(dst)\n                    } catch {\n                        seal.reject(error)\n                    }\n                }.resume()\n            }\n\n        }.then(on: .global(QoS: .userInitiated)) {\n            try Data(contentsOf: $0)\n        }\n\n        active[url] = promise\n\n        if cleanup.isFulfilled {\n            cleanup = promise!.asVoid().then(on: .global(QoS: .utility), execute: docleanup)\n        }\n    }\n\n    return promise!\n}\n\npublic func cached(image url: URL) -> Data? {\n    guard let dst = try? url.cacheDestination() else {\n        return nil\n    }\n    return try? Data(contentsOf: dst)\n}\n\n\npublic func cache(destination remoteUrl: URL) throws -> URL {\n    return try remoteUrl.cacheDestination()\n}\n\nprivate func cache() throws -> URL {\n    guard let dst = FileManager.default.docs?\n        .appendingPathComponent(\"Library\")\n        .appendingPathComponent(\"Caches\")\n        .appendingPathComponent(\"cache.img\")\n    else {\n        throw E.unexpectedError\n    }\n\n    try FileManager.default.createDirectory(at: dst, withIntermediateDirectories: true, attributes: [:])\n\n    return dst\n}\n\nprivate extension URL {\n    func cacheDestination() throws -> URL {\n\n        var fn = String(hashValue)\n        let ext = pathExtension\n\n        // many of Apple's functions don’t recognize file type\n        // unless we preserve the file extension\n        if !ext.isEmpty {\n            fn += \".\\(ext)\"\n        }\n\n        return try cache().appendingPathComponent(fn)\n    }\n}\n\nenum E: Error {\n    case unexpectedError\n    case noCreationTime\n}\n\nprivate func docleanup() throws {\n    var contents = try FileManager.default\n        .contentsOfDirectory(at: try cache(), includingPropertiesForKeys: [.creationDateKey])\n        .map { url -> (Date, URL) in\n            guard let date = try url.resourceValues(forKeys: [.creationDateKey]).creationDate else {\n                throw E.noCreationTime\n            }\n            return (date, url)\n        }.sorted(by: {\n            $0.0 > $1.0\n        })\n\n    while contents.count > 10 {\n        let rm = contents.popLast()!.1\n        try FileManager.default.removeItem(at: rm)\n    }\n}\n````"
  },
  {
    "path": "Documentation/Examples/URLSession+BadResponseErrors.swift",
    "content": "Promise(.pending) { seal in\n    URLSession.shared.dataTask(with: rq, completionHandler: { data, rsp, error in\n        if let data = data {\n            seal.fulfill(data)\n        } else if let error = error {\n            if case URLError.badServerResponse = error, let rsp = rsp as? HTTPURLResponse {\n                seal.reject(Error.badResponse(rsp.statusCode))\n            } else {\n                seal.reject(error)\n            }\n        } else {\n            seal.reject(PMKError.invalidCallingConvention)\n        }\n    })\n}\n\nenum Error: Swift.Error {\n    case badUrl\n    case badResponse(Int)\n}\n"
  },
  {
    "path": "Documentation/Examples/detweet.swift",
    "content": "#!/usr/bin/swift sh\nimport Foundation\nimport PromiseKit  // @mxcl ~> 6.5 \nimport Swifter     // @mattdonnelly == b27a89\nlet swifter = Swifter(\n\tconsumerKey: \"FILL\",\n\tconsumerSecret: \"ME\",\n\toauthToken: \"IN\",\n\toauthTokenSecret: \"https://developer.twitter.com/en/docs/basics/apps/overview.html\"\n)\n\nextension JSON {\n    var date: Date? {\n        guard let string = string else { return nil }\n\n        let formatter = DateFormatter()\n        formatter.dateFormat = \"EEE MMM dd HH:mm:ss Z yyyy\"\n        return formatter.date(from: string)\n    }\n}\n\nlet twoMonthsAgo = Date() - 24*60*60*30*2\n\nprint(\"Deleting qualifying tweets before:\", twoMonthsAgo)\n\nfunc deleteTweets(maxID: String? = nil) -> Promise<Void> {\n    return Promise { seal in\n        swifter.getTimeline(for: \"mxcl\", count: 200, maxID: maxID, success: { json in\n\n            if json.array!.count <= 1 {\n                // if we get one result for a requested maxID, we're done\n                return seal.fulfill()\n            }\n\n            for item in json.array! {\n                let date = item[\"created_at\"].date!\n                guard date < twoMonthsAgo, item[\"favorite_count\"].integer! < 2 else {\n                    continue\n                }\n                swifter.destroyTweet(forID: id, success: { _ in\n                    print(\"D:\", item[\"text\"].string!)\n                }, failure: seal.reject)\n            }\n\n            let next = json.array!.last![\"id_str\"].string!\n            deleteTweets(maxID: next).pipe(to: seal.resolve)\n\n        }, failure: seal.reject)\n    }\n}\n\nfunc deleteFavorites(maxID: String? = nil) -> Promise<Void> {\n    return Promise { seal in\n        swifter.getRecentlyFavoritedTweets(count: 200, maxID: maxID, success: { json in\n\n            if json.array!.count <= 1 {\n                return seal.fulfill()\n            }\n\n            for item in json.array! {\n                guard item[\"created_at\"].date! < twoMonthsAgo else { continue }\n\n                swifter.unfavoriteTweet(forID: item[\"id_str\"].string!, success: { _ in\n                    print(\"D❤️:\", item[\"text\"].string!)\n                }, failure: seal.reject)\n            }\n            \n            let next = json.array!.last![\"id_str\"].string!\n            deleteFavorites(maxID: next).pipe(to: seal.resolve)\n\n        }, failure: seal.reject)\n    }\n}\n\nfunc unblockPeople(cursor: String? = nil) -> Promise<Void> {\n    return Promise { seal in\n        swifter.getBlockedUsersIDs(stringifyIDs: \"true\", cursor: cursor, success: { json, prev, next in\n            for id in json.array! {\n                print(\"Unblocking:\", id)\n                swifter.unblockUser(for: .id(id.string!))\n            }\n\n            if let next = next, !next.isEmpty, next != prev, next != \"0\" {\n                unblockPeople(cursor: next).pipe(to: seal.resolve)\n            } else {\n                seal.fulfill()\n            }\n\n        }, failure: seal.reject)\n    }\n}\n\nfirstly {\n    when(fulfilled: deleteTweets(), deleteFavorites(), unblockPeople())\n}.done {\n    exit(0)\n}.catch {\n    print(\"error:\", $0)\n    exit(1)\n}\n\nRunLoop.main.run()\n"
  },
  {
    "path": "Documentation/FAQ.md",
    "content": "# FAQ\n\n## Why should I use PromiseKit over X-Promises-Foo?\n\n* PromiseKit has a heavy focus on **developer experience**. You’re a developer; do you care about your experience? Yes? Then pick PromiseKit.\n* Do you care about having any bugs you find fixed? Then pick PromiseKit.\n* Do you care about having your input heard and reacted to in a fast fashion? Then pick PromiseKit.\n* Do you want a library that has been maintained continuously and passionately for 6 years? Then pick PromiseKit.\n* Do you want a library that the community has chosen to be their №1 Promises/Futures library? Then pick PromiseKit.\n* Do you want to be able to use Promises with Apple’s SDKs rather than having to do all the work of writing the Promise implementations yourself? Then pick PromiseKit.\n* Do you want to be able to use Promises with Swift 3.x, Swift 4.x, ObjC, iOS, tvOS, watchOS, macOS, Android & Linux? Then pick PromiseKit.\n* PromiseKit verifies its correctness by testing against the entire [Promises/A+ test suite](https://github.com/promises-aplus/promises-tests).\n\n## How do I create a fulfilled `Void` promise?\n\n```swift\nlet foo = Promise()\n\n// or:\n\nlet bar = Promise.value(())\n```\n\n## How do I “early `return`”?\n\n```swift\nfunc foo() -> Promise<Void> {\n   guard thingy else {\n       return Promise()\n   }\n\n    //…\n}\n\nfunc bar() -> Promise<SomethingNotVoid> {\n    guard thingy else {\n        return .value(instanceOfSomethingNotVoid)\n    }\n    \n    //…\n}\n```\n\n## Do I need to worry about retain cycles?\n\nGenerally, no. Once a promise completes, all handlers are released and so\nany references to `self` are also released.\n\nHowever, if your chain contains side effects that you would typically\nnot want to happen after, say, a view controller is popped, then you should still\nuse `weak self` (and check for `self == nil`) to prevent any such side effects.\n\n*However*, in our experience most things that developers consider side effects that\nshould be protected against are in fact *not* side effects.\n\nSide effects include changes to global application state. They *do not* include\nchanging the display state of a view-controller. So, protect against setting `UserDefaults` or\nmodifying the application database, and don't bother protecting against changing\nthe text in a `UILabel`.\n\n[This StackOverflow question](https://stackoverflow.com/questions/39281214/should-i-use-weak-self-in-promisekit-blocks)\nhas some good discussion on this topic.\n\n## Do I need to retain my promises?\n\nNo. Every promise handler retains its promise until the handler is executed. Once\nall handlers have been executed, the promise is deallocated. So you only need to retain\nthe promise if you need to refer to its final value after its chain has completed.\n\n## Where should I put my `catch`?\n\n`catch` deliberately terminates the chain. You should put it low in your promise\nhierarchy at a point as close to the root as possible. Typically, this would be \nsomewhere such as a view controller, where your `catch` can then display a message\nto the user.\n\nThis means you should be writing one catch for many `then`s and returning\npromises that do not have internal `catch` handlers of their own.\n\nThis is obviously a guideline; do what is necessary.\n\n## How do branched chains work?\n\nSuppose you have a promise:\n\n```\nlet promise = foo()\n```\n\nAnd you call `then` twice:\n\n```\npromise.then {\n    // branch A\n}\n\npromise.then {\n    // branch B\n}\n```\n\nYou now have a branched chain. When `promise` resolves, both chains receive its\nvalue. However, the two chains are entirely separate and Swift will prompt you\nto ensure that both have `catch` handlers.\n\nYou can most likely ignore the `catch` for one of these branches, but be careful:\nin these situations, Swift cannot help you ensure that your chains are error-handled.\n\n```\npromise.then {\n    // branch A\n}.catch { error in\n    //…\n}\n\n_ = promise.then {\n    print(\"foo\")\n    \n    // ignoring errors here as print cannot error and we handle errors above\n}\n```\n\nIt may be safer to recombine the two branches into a single chain again:\n\n```\nlet p1 = promise.then {\n    // branch A\n}\n\nlet p2 = promise.then {\n    // branch B\n}\n\nwhen(fulfilled: p1, p2).catch { error in\n    //…\n}\n```\n\n> It's worth noting that you can add multiple `catch` handlers to a promise, too.\n> And indeed, both will be called if the chain is rejected.\n\n## Is PromiseKit “heavy”?\n\nNo. PromiseKit contains hardly any source code. In fact, it is quite lightweight. Any\n“weight” relative to other promise implementations derives from 6 years of bug fixes\nand tuning, from the fact that we have *stellar* Objective-C-to-Swift bridging and \nfrom important things such as [Zalgo prevention](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)\nthat hobby-project implementations don’t consider.\n\n## Why is debugging hard?\n\nBecause promises always execute via dispatch, the backtrace you see at the point of \nan error has less information than is usually required to trace the path of execution.\n\nOne solution is to turn off dispatch during debugging:\n\n```swift\n// Swift\nDispatchQueue.default = zalgo\n\n//ObjC\nPMKSetDefaultDispatchQueue(zalgo)\n```\n\nDon’t leave this on. In normal use, we always dispatch to avoid you accidentally writing\na common bug pattern. See [this blog post](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony).\n\n## Where is `all()`?\n\nSome promise libraries provide `all` for awaiting multiple results. We call this function\n`when`, but it is the same thing. We chose `when` because it's the more common term and\nbecause we think it reads better in code.\n\n## How can I test APIs that return promises?\n\nYou need to use `XCTestExpectation`.\n\nWe also define `wait()` and `hang()`. Use them if you must, but be careful because they\nblock the current thread!\n\n## Is PromiseKit thread-safe?\n\nYes, entirely.\n\nHowever the code *you* write in your `then`s might not be!\n\nJust make sure you don’t access state outside the chain from concurrent queues.\nBy default, PromiseKit handlers run on the `main` thread, which is serial, so\nyou typically won't have to worry about this.\n\n## Why are there separate classes for Objective-C and Swift?\n\n`Promise<T>` is generic and and so cannot be represented by Objective-C.\n\n## Does PromiseKit conform to Promises/A+?\n\nYes. We have tests that prove this.\n\n## How do PromiseKit and RxSwift/ReactiveSwift differ?\n\nPromiseKit is a lot simpler.\n\nThe top-level difference between PromiseKit and RxSwift is that RxSwift `Observable`s (roughly \nanalogous to PromiseKit `Promise`s) do not necessarily return a single result: they may emit\nzero, one, or an infinite stream of values. This small conceptual change leads to an API\nthat's both surprisingly powerful and surprisingly complex.\n\nRxSwift requires commitment to a paradigm shift in how you program. It proposes that you\nrestructure your code as a matrix of interacting value pipelines. When applied properly\nto a suitable problem, RxSwift can yield great benefits in robustness and simplicity.\nBut not all applications are suitable for RxSwift. \n\nBy contrast, PromiseKit selectively applies the best parts of reactive programming\nto the hardest part of pure Swift development, the management of asynchronicity. It's a broadly \napplicable tool. Most asynchronous code can be clarified, simplified and made more robust\njust by converting it to use promises. (And the conversion process is easy.)\n\nPromises make for code that is clear to most developers. RxSwift, perhaps not. Take a look at this \n[sign-up panel](https://github.com/ReactiveX/RxSwift/tree/master/RxExample/RxExample/Examples/GitHubSignup)\nimplemented in RxSwift and see what you think. (Note that this is one of RxSwift's own examples.)\n\nEven where PromiseKit and RxSwift are broadly similar, there are many differences in implementation:\n\n* RxSwift has a separate API for chain-terminating elements (\"subscribers\") versus interior\nelements. In PromiseKit, all elements of a chain use roughly the same code pattern.\n\n* The RxSwift API to define an interior element of a chain (an \"operator\") is hair-raisingly complex.\nSo, RxSwift tries hard to supply every operator you might ever want to use right off the shelf. There are\nhundreds. PromiseKit supplies a few utilities to help with specific scenarios, but because it's trivial\nto write your own chain elements, there's no need for all this extra code in the library.\n\n* PromiseKit dispatches the execution of every block. RxSwift dispatches only when told to do so. Moreover, the \ncurrent dispatching state is an attribute of the chain, not the specific block, as it is in PromiseKit.\nThe RxSwift system is more powerful but more complex. PromiseKit is simple, predictable and safe.\n\n* In PromiseKit, both sides of a branched chain refer back to their shared common ancestors. In RxSwift, \nbranching normally creates a duplicate parallel chain that reruns the code at the head of the chain...except \nwhen it doesn't. The rules for determining what will actually happen are complex, and given\na chain created by another chunk of code, you can't really tell what the behavior will be.\n\n* Because RxSwift chains don't necessarily terminate on their own, RxSwift needs you to take on some\nexplicit garbage collection duties to ensure that pipelines that are no longer needed are properly\ndeallocated. All promises yield a single value, terminate and then automatically deallocate themselves.\n\nYou can find some additional discussion in [this ticket](https://github.com/mxcl/PromiseKit/issues/484).\n\n## Why can’t I return from a catch like I can in JavaScript?\n\nSwift demands that functions have one purpose. Thus, we have two error handlers:\n\n* `catch`: ends the chain and handles errors\n* `recover`: attempts to recover from errors in a chain\n\nYou want `recover`.\n\n## When do promises “start”?\n\nOften people are confused about when Promises “start”. Is it immediately? Is it\nlater? Is it when you call `then`?\n\nThe answer is: The promise **body** executes during initialization of the promise, on the current thread.\nAs an example, `\"Executing the promise body\"` will be printed to the console right after the promise is created,\nwithout having to call `then` on the promise.\n\n```swift\nlet testPromise = Promise<Bool> {\n    print(\"Executing the promise body.\")\n    return $0.fulfill(true)\n}\n```\n\nBut what about asynchronous tasks that you create in your promise's body? They behave the same way as they would\nwithout using PromiseKit. Here's a simple example:\n\n```swift\nlet testPromise = Promise<Bool> { seal in\n    print(\"Executing the promise body.\")\n    DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {\n        print(\"Executing asyncAfter.\")\n        return seal.fulfill(true)\n    }\n}\n```\n\nThe message `\"Executing the promise body.\"` is being logged right away, but the message `\"Executing asyncAfter.\"`\nis only logged three seconds later. In this case `DispatchQueue` is responsible for deciding when to execute\nthe task you pass to it, PromiseKit has nothing to do with it.\n\n## What is a good way to use Firebase with PromiseKit\n\nThere is no good way to use Firebase with PromiseKit. See the next question for\na more detailed rationale.\n\nThe best option is to embed your chain in your Firebase handler:\n\n```\nfoo.observe(.value) { snapshot in\n    firstly {\n        bar(with: snapshot)\n    }.then {\n        baz()\n    }.then {\n        baffle()\n    }.catch {\n        //…\n    }\n}\n```\n\n\n## I need my `then` to fire multiple times\n\nThen we’re afraid you cannot use PromiseKit for that event. Promises only\nresolve *once*. This is the fundamental nature of promises and it is considered a\nfeature because it gives you guarantees about the flow of your chains.\n\n\n## How do I change the default queues that handlers run on?\n\nYou can change the values of `PromiseKit.conf.Q`. There are two variables that\nchange the default queues that the two kinds of handler run on. A typical\npattern is to change all your `then`-type handlers to run on a background queue\nand to have all your “finalizers” run on the main queue:\n\n```\nPromiseKit.conf.Q.map = .global()\nPromiseKit.conf.Q.return = .main  //NOTE this is the default\n```\n\nBe very careful about setting either of these queues to `nil`.  It has the\neffect of running *immediately*, and this is not what you usually want to do in\nyour application.  This is, however, useful when you are running specs and want\nyour promises to resolve immediately. (This is basically the same idea as \"stubbing\"\nan HTTP request.)\n\n```swift\n// in your test suite setup code\nPromiseKit.conf.Q.map = nil\nPromiseKit.conf.Q.return = nil\n```\n\n## How do I use PromiseKit on the server side?\n\nIf your server framework requires that the main queue remain unused (e.g., Kitura),\nthen you must use PromiseKit 6 and you must tell PromiseKit not to dispatch to the\nmain queue by default. This is easy enough:\n\n```swift\nPromiseKit.conf.Q = (map: DispatchQueue.global(), return: DispatchQueue.global())\n```\n\n> Note, we recommend using your own queue rather than `.global()`, we've seen better performance this way.\n\nHere’s a more complete example:\n\n```swift\nimport Foundation\nimport HeliumLogger\nimport Kitura\nimport LoggerAPI\nimport PromiseKit\n\nHeliumLogger.use(.info)\n\nlet pmkQ = DispatchQueue(label: \"pmkQ\", qos: .default, attributes: .concurrent, autoreleaseFrequency: .workItem)\nPromiseKit.conf.Q = (map: pmkQ, return: pmkQ)\n\nlet router = Router()\nrouter.get(\"/\") { _, response, next in\n    Log.info(\"Request received\")\n    after(seconds: 1.0).done {\n        Log.info(\"Sending response\")\n        response.send(\"OK\")\n        next()\n    }\n}\n\nLog.info(\"Starting server\")\nKitura.addHTTPServer(onPort: 8888, with: router)\nKitura.run()\n```\n\n## How do I control console output?\n\nBy default PromiseKit emits console messages when certain events occur.  These events include:\n- A promise or guarantee has blocked the main thread\n- A promise has been deallocated without being fulfilled\n- An error which occurred while fulfilling a promise was swallowed using cauterize\n\nYou may turn off or redirect this output by setting a thread safe closure in [PMKConfiguration](https://github.com/mxcl/PromiseKit/blob/master/Sources/Configuration.swift) **before** processing any promises. For example, to turn off console output:\n\n```swift\nconf.logHandler = { event in }\n```\n\n## My question was not answered\n\n[Please open a ticket](https://github.com/mxcl/PromiseKit/issues/new).\n"
  },
  {
    "path": "Documentation/GettingStarted.md",
    "content": "# `then` and `done`\n\nHere is a typical promise chain:\n\n```swift\nfirstly {\n    login()\n}.then { creds in\n    fetch(avatar: creds.user)\n}.done { image in\n    self.imageView = image\n}\n```\n\nIf this code used completion handlers, it would look like this:\n\n```swift\nlogin { creds, error in\n    if let creds = creds {\n        fetch(avatar: creds.user) { image, error in\n            if let image = image {\n                self.imageView = image\n            }\n        }\n    }\n}\n```\n\n`then` *is* just another way to structure completion handlers, but it is also quite a\nbit more. At this initial stage of our understanding, it mostly helps\nreadability. The promise chain above is easy to scan and understand: one asynchronous\noperation leads into the other, line by line. It's as close to\nprocedural code as we can easily come given the current state of Swift.\n\n`done` is the same as `then` but you cannot return a promise. It is \ntypically the end of the “success” part of the chain. Above, you can see that we\nreceive the final image in our `done` and use it to set up the UI.\n\nLet’s compare the signatures of the two login methods:\n\n```swift\nfunc login() -> Promise<Creds>\n    \n// Compared with:\n\nfunc login(completion: (Creds?, Error?) -> Void)\n                        // ^^ ugh. Optionals. Double optionals.\n```\n\nThe distinction is that with promises, your functions return *promises* instead \nof accepting and running callbacks. Each handler in a chain returns a promise. \n`Promise` objects define the `then` method, which waits for the completion of the\npromise before continuing the chain. Chains resolve procedurally, one promise\nat a time.\n\nA `Promise` represents the future value of an asynchronous task. It has a type\nthat represents the type of object it wraps. For example, in the example above,\n`login` is a function that returns a `Promise` that *will* represent an instance\nof `Creds`.\n\n> *Note*: `done` is new to PromiseKit 5. We previously defined a variant of `then` that\ndid not require you to return a promise. Unfortunately, this convention often confused\nSwift and led to odd and hard-to-debug error messages. It also made using PromiseKit \nmore painful. The introduction of `done` lets you type out promise chains that\ncompile without additional qualification to help the compiler figure out type information.\n\n---\n\nYou may notice that unlike the completion pattern, the promise chain appears to\nignore errors. This is not the case! In fact, it has the opposite effect: the promise\nchain makes error handling more accessible and makes errors harder to ignore.\n\n\n# `catch`\n\nWith promises, errors cascade along the promise chain, ensuring that your apps are\nrobust and your code is clear:\n\n```swift\nfirstly {\n    login()\n}.then { creds in\n    fetch(avatar: creds.user)\n}.done { image in\n    self.imageView = image\n}.catch {\n    // any errors in the whole chain land here\n}\n```\n\n> Swift emits a warning if you forget to `catch` a chain. But we'll\n> talk about that in more detail later.\n\nEach promise is an object that represents an individual, asynchronous task.\nIf a task fails, its promise becomes *rejected*. Chains that contain rejected\npromises skip all subsequent `then`s. Instead, the next `catch` is executed.\n(Strictly speaking, *all* subsequent `catch` handlers are executed.)\n\nFor fun, let’s compare this pattern with its completion handler equivalent:\n\n```swift\nfunc handle(error: Error) {\n    //…\n}\n\nlogin { creds, error in\n    guard let creds = creds else { return handle(error: error!) }\n    fetch(avatar: creds.user) { image, error in\n        guard let image = image else { return handle(error: error!) }\n        self.imageView.image = image\n    }\n}\n```\n\nThe use of `guard` and a consolidated error handler help, but the promise chain’s\nreadability speaks for itself.\n\n\n# `ensure`\n\nWe have learned to compose asynchronicity. Next let’s extend our primitives:\n\n```swift\nfirstly {\n    UIApplication.shared.isNetworkActivityIndicatorVisible = true\n    return login()\n}.then {\n    fetch(avatar: $0.user)\n}.done {\n    self.imageView = $0\n}.ensure {\n    UIApplication.shared.isNetworkActivityIndicatorVisible = false\n}.catch {\n    //…\n}\n```\n\nNo matter the outcome of your chain—-failure or success—-your `ensure`\nhandler is always called.\n\nLet’s compare this pattern with its completion handler equivalent:\n\n```swift\nUIApplication.shared.isNetworkActivityIndicatorVisible = true\n\nfunc handle(error: Error) {\n    UIApplication.shared.isNetworkActivityIndicatorVisible = false\n    //…\n}\n\nlogin { creds, error in\n    guard let creds = creds else { return handle(error: error!) }\n    fetch(avatar: creds.user) { image, error in\n        guard let image = image else { return handle(error: error!) }\n        self.imageView.image = image\n        UIApplication.shared.isNetworkActivityIndicatorVisible = false\n    }\n}\n```\n\nIt would be very easy for someone to amend this code and forget to unset \nthe activity indicator, leading to a bug. With promises, this type of error is\nalmost impossible: the Swift compiler resists your supplementing the chain without \nusing promises. You almost won’t need to review the pull requests.\n\n> *Note*: PromiseKit has perhaps capriciously switched between the names `always`\nand `ensure` for this function several times in the past. Sorry about this. We suck.\n\nYou can also use `finally` as an `ensure` that terminates the promise chain and does not return a value:\n\n```\nspinner(visible: true)\n\nfirstly {\n    foo()\n}.done {\n    //…\n}.catch {\n    //…\n}.finally {\n    self.spinner(visible: false)\n}\n```\n\n\n# `when`\n\nWith completion handlers, reacting to multiple asynchronous operations is either\nslow or hard. Slow means doing it serially:\n\n```swift\noperation1 { result1 in\n    operation2 { result2 in\n        finish(result1, result2)\n    }\n}\n```\n\nThe fast (*parallel*) path code makes the code less clear:\n\n```swift\nvar result1: …!\nvar result2: …!\nlet group = DispatchGroup()\ngroup.enter()\ngroup.enter()\noperation1 {\n    result1 = $0\n    group.leave()\n}\noperation2 {\n    result2 = $0\n    group.leave()\n}\ngroup.notify(queue: .main) {\n    finish(result1, result2)\n}\n```\n\nPromises are easier:\n\n```swift\nfirstly {\n    when(fulfilled: operation1(), operation2())\n}.done { result1, result2 in\n    //…\n}\n```\n\n`when` takes promises, waits for them to resolve and returns a promise containing the results.\n\nAs with any promise chain, if any of the component promises fail, the chain calls the next `catch`.\n\n\n# PromiseKit Extensions\n\nWhen we made PromiseKit, we understood that we wanted to use *only* promises to implement \nasynchronous behavior. So wherever possible, we offer extensions to Apple’s APIs that reframe\nthe API in terms of promises. For example:\n\n```swift\nfirstly {\n    CLLocationManager.promise()\n}.then { location in\n    CLGeocoder.reverseGeocode(location)\n}.done { placemarks in\n    self.placemark.text = \"\\(placemarks.first)\"\n}\n```\n\nTo use these extensions, you need to specify subspecs:\n\n```ruby\npod \"PromiseKit\"\npod \"PromiseKit/CoreLocation\"\npod \"PromiseKit/MapKit\"\n```\n\nAll of these extensions are available at the [PromiseKit organization](https://github.com/PromiseKit).\nGo there to see what's available and to read the source code and documentation. Every file and function\nhas been copiously documented.\n\n> We also provide extensions for common libraries such as [Alamofire](https://github.com/PromiseKit/Alamofire-).\n\n\n# Making Promises\n\nThe standard extensions will take you a long way, but sometimes you'll still need to start chains\nof your own. Maybe you're using a third party API that doesn’t provide promises, or perhaps you wrote\nyour own asynchronous system. Either way, it's easy to add promises. If you look at the code of the\nstandard extensions, you'll see that it uses the same approach  described below.\n\nLet’s say we have the following method:\n\n```swift\nfunc fetch(completion: (String?, Error?) -> Void)\n```\n\nHow do we convert this to a promise? Well, it's easy:\n\n```swift\nfunc fetch() -> Promise<String> {\n    return Promise { fetch(completion: $0.resolve) }\n}\n```\n\nYou may find the expanded version more readable:\n\n```swift\nfunc fetch() -> Promise<String> {\n    return Promise { seal in\n        fetch { result, error in\n            seal.resolve(result, error)\n        }\n    }\n}\n```\n\nThe `seal` object that the `Promise` initializer provides to you defines \nmany methods for handling garden-variety completion handlers. It even \ncovers a variety of rarer situations, thus making it easy for you to add \npromises to an existing codebase.\n\n> *Note*: We tried to make it so that you could just do `Promise(fetch)`, but we\nwere not able to make this simpler pattern work universally without requiring\nextra disambiguation for the Swift compiler. Sorry; we tried.\n\n> *Note*: In PMK 4, this initializer provided two parameters to your closure:\n`fulfill` and `reject`. PMK 5 and 6 give you an object that has both `fulfill` and\n`reject` methods, but also many variants of the method `resolve`. You can\ntypically just pass completion handler parameters to `resolve` and let Swift figure\nout which variant to apply to your particular case (as shown in the example above).\n\n> *Note* `Guarantees` (below) have a slightly different initializer (since they\ncannot error) so the parameter to the initializer closure is just a closure. Not\na `Resolver` object. Thus do `seal(value)` rather than `seal.fulfill(value)`. This\nis because there is no variations in what guarantees can be sealed with, they can\n*only* fulfill.\n\n# `Guarantee<T>`\n\nSince PromiseKit 5, we have provided `Guarantee` as a supplementary class to\n`Promise`. We do this to complement Swift’s strong error handling system.\n\nGuarantees *never* fail, so they cannot be rejected. A good example is `after`:\n\n```\nfirstly {\n    after(seconds: 0.1)\n}.done {\n    // there is no way to add a `catch` because after cannot fail.\n}\n```\n\nSwift warns you if you don’t terminate a regular `Promise` chain (i.e., not\na `Guarantee` chain). You're expected to silence this warning by supplying \neither a `catch` or a `return`. (In the latter case, you will then have to `catch` \nat the point where you receive that promise.)\n\nUse `Guarantee`s wherever possible so that your code has error handling where\nit's required and no error handling where it's not required.\n\nIn general, you should be able to use `Guarantee`s and `Promise`s interchangeably,\nWe have gone to great lengths to try and ensure this, so please open a ticket\nif you find an issue.\n\n---\n\nIf you are creating your own guarantees the syntax is simpler than that of promises;\n\n```swift\nfunc fetch() -> Promise<String> {\n    return Guarantee { seal in\n        fetch { result in\n            seal(result)\n        }\n    }\n}\n```\n\nWhich could be reduced to:\n\n```swift\nfunc fetch() -> Promise<String> {\n    return Guarantee(resolver: fetch)\n}\n```\n\n# `map`, `compactMap`, etc.\n\n`then` provides you with the result of the previous promise and requires you to return\nanother promise.\n\n`map` provides you with the result of the previous promise and requires you to return\nan object or value type.\n\n`compactMap` provides you with the result of the previous promise and requires you\nto return an `Optional`. If you return `nil`, the chain fails with\n`PMKError.compactMap`.\n\n> *Rationale*: Before PromiseKit 4, `then` handled all these cases, and it was\npainful. We hoped the pain would disappear with new Swift versions. However,\nit has become clear that the various pain points are here to stay. In fact, we\nas library authors are expected to disambiguate at the naming level of our API.\nTherefore, we have split the three main kinds of `then` into `then`, `map` and\n`done`. After using these new functions, we realized this is much nicer in practice,\nso we added `compactMap` as well (modeled on `Optional.compactMap`).\n\n`compactMap` facilitates quick composition of promise chains. For example:\n\n```swift\nfirstly {\n    URLSession.shared.dataTask(.promise, with: rq)\n}.compactMap {\n    try JSONSerialization.jsonObject($0.data) as? [String]\n}.done { arrayOfStrings in\n    //…\n}.catch { error in\n    // Foundation.JSONError if JSON was badly formed\n    // PMKError.compactMap if JSON was of different type\n}\n```\n\n> *Tip*: We also provide most of the functional methods you would expect for sequences,\ne.g., `map`, `thenMap`, `compactMapValues`, `firstValue`, etc.\n\n\n# `get`\n\nWe provide `get` as a `done` that returns the value fed to `get`.\n\n```swift\nfirstly {\n    foo()\n}.get { foo in\n    //…\n}.done { foo in\n    // same foo!\n}\n```\n\n\n# `tap`\n\nWe provide `tap` for debugging. It's the same as `get` but provides the\n`Result<T>` of the `Promise` so you can inspect the value of the chain at this\npoint without causing any side effects:\n\n```swift\nfirstly {\n    foo()\n}.tap {\n    print($0)\n}.done {\n    //…\n}.catch {\n    //…\n}\n```\n\n\n# Supplement\n\n## `firstly`\n\nWe've used `firstly` several times on this page, but what is it, really? In fact,\nit is just [syntactic sugar](https://en.wikipedia.org/wiki/Syntactic_sugar).\nYou don’t really need it, but it helps to make your chains more readable. Instead of:\n\n```swift\nfirstly {\n    login()\n}.then { creds in\n    //…\n}\n```\n\nYou could just do:\n\n```swift\nlogin().then { creds in\n    //…\n}\n```\n\nHere is a key understanding: `login()` returns a `Promise`, and all `Promise`s have a `then` function. `firstly` returns a `Promise`, and `then` returns a `Promise`, too! But don’t worry too much about these details. Learn the *patterns* to start with. Then, when you are ready to advance, learn the underlying architecture.\n\n\n## `when` Variants\n\n`when` is one of PromiseKit’s more useful functions, and so we offer several variants.\n\n* The default `when`, and the one you should typically use, is `when(fulfilled:)`. This variant\nwaits on all its component promises, but if any fail, `when` fails too, and thus the chain *rejects*. \nIt's important to note that all promises in the `when` *continue*. Promises have *no* control over\nthe tasks they represent. Promises are just wrappers around tasks.\n\n* `when(resolved:)` waits even if one or more of its component promises fails. The value produced\nby this variant of `when` is an array of `Result<T>`. Consequently, this variant requires all its \ncomponent promises to have the same generic type. See our advanced patterns guide for work-arounds\nfor this limitation.\n\n* The `race` variant lets you *race* several promises. Whichever finishes first is the result. See the\nadvanced patterns guide for typical usage.\n\n\n## Swift Closure Inference\n\nSwift automatically infers returns and return types for one-line closures.\nThe following two forms are the same:\n\n```swift\nfoo.then {\n    bar($0)\n}\n\n// is the same as:\n\nfoo.then { baz -> Promise<String> in\n    return bar(baz)\n}\n```\n\nOur documentation often omits the `return` for clarity.\n\nHowever, this shorthand is both a blessing and a curse. You may find that the Swift compiler\noften fails to infer return types properly. See our [Troubleshooting Guide](Troubleshooting.md) if\nyou require further assistance.\n\n> By adding `done` to PromiseKit 5, we have managed to avoid many of these common\npain points in using PromiseKit and Swift.\n\n\n\n# Further Reading\n\nThe above information is the 90% you will use. We **strongly** suggest reading the\n[API Reference].\nThere are numerous little\nfunctions that may be useful to you, and the documentation for everything outlined above\nis more thorough at the source.\n\nIn Xcode, don’t forget to option-click on PromiseKit functions to access this\ndocumentation while you're coding.\n\nHere are some recent articles that document PromiseKit 5+:\n\n* [Using Promises - Agostini.tech](https://agostini.tech/2018/10/08/using-promisekit)\n\nCareful with general online references, many of them refer to PMK < 5 which has a subtly\ndifferent API (sorry about that, but Swift has changed a lot over the years and thus\nwe had to too).\n\n\n[API Reference]: https://mxcl.dev/PromiseKit/reference/v6/Classes/Promise.html\n"
  },
  {
    "path": "Documentation/Installation.md",
    "content": "# Xcode 8.3, 9.x or 10.x / Swift 3 or 4\n\nWe recommend Carthage over CocoaPods, but both installation methods are supported.\n\n## CocoaPods\n\n```ruby\nuse_frameworks!\n\ntarget \"Change Me!\" do\n  pod \"PromiseKit\", \"~> 6.8\"\nend\n```\n\nIf the generated Xcode project gives you a warning that PromiseKit needs to be upgraded to\nSwift 4.0 or Swift 4.2, then add the following:\n\n```ruby\npost_install do |installer|\n  installer.pods_project.targets.each do |target|\n    if target.name == 'PromiseKit'\n      target.build_configurations.each do |config|\n        config.build_settings['SWIFT_VERSION'] = '4.2'\n      end\n    end\n  end\nend\n```\n\nAdjust the value for `SWIFT_VERSION` as needed.\n\nCocoaPods are aware of this [issue](https://github.com/CocoaPods/CocoaPods/issues/7134).\n\n## Carthage\n\n```ruby\ngithub \"mxcl/PromiseKit\" ~> 6.8\n```\n\n> Please note, since PromiseKit 6.8.1 our Carthage support has transitioned to\n> Swift 4 and above only. Strictly we *do* still support Swift 3.1 for Carthage,\n> and if you like you could edit the PromiseKit `project.pbxproj` file during\n> `carthage bootstrap` to make this possible. This change was involuntary and due\n> to Xcode 10.2 dropping support for Swift 3.\n\nFrom Xcode 12, you will likely need to build using `--use-xcframeworks`, eg:\n\n    carthage build --use-xcframeworks\n\n## Accio\n\nAdd the following to your Package.swift:\n\n```swift\n.package(url: \"https://github.com/mxcl/PromiseKit.git\", .upToNextMajor(from: \"6.8.4\")),\n```\n\nNext, add `PromiseKit` to your App targets dependencies like so:\n\n```swift\n.target(\n    name: \"App\",\n    dependencies: [\n        \"PromiseKit\",\n    ]\n),\n```\n\nThen run `accio update`.\n\n## SwiftPM\n\n```swift\npackage.dependencies.append(\n    .package(url: \"https://github.com/mxcl/PromiseKit\", from: \"6.8.0\")\n)\n```\n\n## Manually\n\nYou can just drop `PromiseKit.xcodeproj` into your project and then add\n`PromiseKit.framework` to your app’s embedded frameworks.\n\n\n# PromiseKit vs. Xcode\n\nPromiseKit contains Swift, so there have been rev-lock issues with Xcode:\n\n| PromiseKit | Swift                   | Xcode    |   CI Status  |   Release Notes   |\n| ---------- | ----------------------- | -------- | ------------ | ----------------- |\n|      6     |      3.2, 3.3, 4.x, 5.x | 8.3, 9.x, 10.x | ![ci-master] | [2018/02][news-6] |\n|      5     | 3.1, 3.2, 3.3, 4.x      | 8.3, 9.x, 10.1 | *Deprecated* |       *n/a*       |\n|      4     | 3.0, 3.1, 3.2, 3.3, 4.x | 8.x, 9.x, 10.1 | ![ci-master] | [2016/09][news-4] |\n|      3     | 2.x                     | 7.x, 8.0 | ![ci-swift2] | [2015/10][news-3] |\n|      2     | 1.x                     | 7.x      | *Deprecated* | [2015/10][news-3] |\n|      1†    | *N/A*                   | *        | ![ci-legacy] |         –         |\n\n† PromiseKit 1 is pure Objective-C and thus can be used with any Xcode, it is\nalso your only choice if you need to support iOS 7 or below.\n\n---\n\nWe also maintain a series of branches to aid migration for PromiseKit 2:\n\n| Xcode | Swift | PromiseKit | Branch                      | CI Status |\n| ----- | ----- | -----------| --------------------------- | --------- |\n|  8.0  |  2.3  | 2          | [swift-2.3-minimal-changes] | ![ci-23]  |\n|  7.3  |  2.2  | 2          | [swift-2.2-minimal-changes] | ![ci-22]  |\n|  7.2  |  2.2  | 2          | [swift-2.2-minimal-changes] | ![ci-22]  |\n|  7.1  |  2.1  | 2          | [swift-2.0-minimal-changes] | ![ci-20]  |\n|  7.0  |  2.0  | 2          | [swift-2.0-minimal-changes] | ![ci-20]  |\n\nWe do **not** usually backport fixes to these branches, but pull requests are welcome.\n\n\n## Xcode 8 / Swift 2.3 or Xcode 7\n\n```ruby\n# CocoaPods\nswift_version = \"2.3\"\npod \"PromiseKit\", \"~> 3.5\"\n\n# Carthage\ngithub \"mxcl/PromiseKit\" ~> 3.5\n```\n\n\n[travis]: https://travis-ci.org/mxcl/PromiseKit\n[ci-master]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=master\n[ci-legacy]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=legacy-1.x\n[ci-swift2]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.x\n[ci-23]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.3-minimal-changes\n[ci-22]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.2-minimal-changes\n[ci-20]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.0-minimal-changes\n[news-2]: http://mxcl.dev/PromiseKit/news/2015/05/PromiseKit-2.0-Released/\n[news-3]: https://github.com/mxcl/PromiseKit/blob/212f31f41864d1e3ec54f5dd529bd8e1e5697024/CHANGELOG.markdown#300-oct-1st-2015\n[news-4]: http://mxcl.dev/PromiseKit/news/2016/09/PromiseKit-4.0-Released/\n[news-6]: http://mxcl.dev/PromiseKit/news/2018/02/PromiseKit-6.0-Released/\n[swift-2.3-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.3-minimal-changes\n[swift-2.2-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.2-minimal-changes\n[swift-2.0-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.0-minimal-changes\n\n\n# Using Git Submodules for PromiseKit’s Extensions\n\n> *Note*: This is a more advanced technique.\n\nIf you use CocoaPods and a few PromiseKit extensions, then importing PromiseKit\ncauses that module to import all the extension frameworks. Thus, if you have an\napp and a few app extensions (e.g., iOS app, iOS watch extension, iOS Today\nextension) then all your final products that use PromiseKit will have forced\ndependencies on all the Apple frameworks that PromiseKit provides extensions\nfor.\n\nThis isn’t that bad, but every framework that loads entails overhead and\nlengthens startup time.\n\nIt’s both better and worse with Carthage. We build individual micro-frameworks\nfor each PromiseKit extension, so your final products link\nagainst only the Apple frameworks that they actually need. However, Apple has\nadvised that apps link only against “about 12” frameworks for performance\nreasons. So with Carthage, we are worse off on this metric.\n\nThe solution is to instead import only CorePromise:\n\n```ruby\n# CocoaPods\npod \"PromiseKit/CorePromise\"\n\n# Carthage\ngithub \"mxcl/PromiseKit\"\n# ^^ for Carthage *only* have this\n```\n\nAnd to use the extensions you need via `git submodules`:\n\n```\ngit submodule init\ngit submodule add https://github.com/PromiseKit/UIKit Submodules/PMKUIKit\n```\n\nThen in Xcode you can add these sources to your targets on a per-target basis.\n\nThen when you `pod update`, ensure that you also update your submodules:\n\n    pod update && git submodule update --recursive --remote\n\n\n\n# Release History\n\n## [6.0](https://github.com/mxcl/PromiseKit/releases/tag/6.0.0) Feb 13th, 2018\n\n* [PromiseKit 6 announcement post][news-6].\n\n## [4.0](https://github.com/mxcl/PromiseKit/releases/tag/4.0.0)\n\n* [PromiseKit 4 announcement post][news-4].\n\n## [3.0](https://github.com/mxcl/PromiseKit/releases/tag/3.0.0) Oct 1st, 2015\n\nIn Swift 2.0 `catch` and `defer` became reserved keywords mandating we rename\nour functions with these names. This forced a major semantic version change on\nPromiseKit and thus we took the opportunity to make other minor (source\ncompatibility breaking) improvements.\n\nThus if you cannot afford to adapt to PromiseKit 3 but still want to use\nXcode-7.0/Swift-2.0 we provide a [minimal changes branch] where `catch` and\n`defer` are renamed `catch_` and `defer_` and all other changes are the bare\nminimum to make PromiseKit 2 compile against Swift 2.\n\nIf you still are using Xcode 6 and Swift 1.2 then use PromiseKit 2.\n\n[minimal changes branch]: https://github.com/mxcl/PromiseKit/tree/swift-2.0-minimal-changes\n\n## [2.0](https://github.com/mxcl/PromiseKit/releases/tag/2.0.0) May 14th, 2015\n\n[PromiseKit 2 announcement post](http://mxcl.dev/PromiseKit/news/2015/05/PromiseKit-2.0-Released/).\n\n## [1.5](https://github.com/mxcl/PromiseKit/releases/tag/1.5.0)\n\nSwift 1.2 support. Xcode 6.3 required.\n"
  },
  {
    "path": "Documentation/ObjectiveC.md",
    "content": "# Objective-C\n\nPromiseKit has two promise classes:\n\n* `Promise<T>` (Swift)\n* `AnyPromise` (Objective-C)\n\nEach is designed to be an appropriate promise implementation for the strong points of its language:\n\n* `Promise<T>` is strict, defined and precise.\n* `AnyPromise` is loose and dynamic.\n\nUnlike most libraries, we have extensive bridging support, you can use PromiseKit\nin mixed projects with mixed language targets and mixed language libraries.\n\n\n# Using PromiseKit with Objective-C\n\n`AnyPromise` is our promise class for Objective-C. It behaves almost identically to `Promise<T>`, our Swift promise class.\n\n```objc\nmyPromise.then(^(NSString *bar){\n    return anotherPromise;\n}).then(^{\n    //…\n}).catch(^(NSError *error){\n    //…\n});\n```\n\nYou make new promises using `promiseWithResolverBlock`:\n\n```objc\n- (AnyPromise *)myPromise {\n    return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve){\n        resolve(foo);  // if foo is an NSError, rejects, else, resolves\n    }];\n}\n```\n\n---\n\nYou reject promises by throwing errors:\n\n```objc\nmyPromise.then(^{\n    @throw [NSError errorWithDomain:domain code:code userInfo:nil];\n}).catch(^(NSError *error){\n    //…\n});\n```\n\nOne important feature is the syntactic flexibility of your handlers:\n\n```objc\nmyPromise.then(^{\n    // no parameters is fine\n});\n\nmyPromise.then(^(id foo){\n    // one parameter is fine\n});\n\nmyPromise.then(^(id a, id b, id c){\n    // up to three parameter is fine, no crash!\n});\n\nmyPromise.then(^{\n    return @1; // return anything or nothing, it's fine, no crash\n});\n```\n\nWe do runtime inspection of the block you pass to achieve this magic.\n\n---\n\nAnother important distinction is that the equivalent function to Swift’s `recover` is combined with `AnyPromise`’s `catch`. This is typical to other “dynamic” promise implementations and thus achieves our goal that `AnyPromise` is loose and dynamic while `Promise<T>` is strict and specific.\n\nA sometimes unexpected consequence of this fact is that returning nothing from a `catch` *resolves* the returned promise:\n\n```objc\nmyPromise.catch(^{\n    [UIAlertView …];\n}).then(^{\n    // always executes!\n});\n```\n\n---\n\nAnother important distinction is that the `value` property returns even if the promise is rejected; in that case, it returns the `NSError` object with which the promise was rejected.\n\n\n# Bridging Between Objective-C & Swift\n\nLet’s say you have:\n\n```objc\n@interface Foo\n- (AnyPromise *)myPromise;\n@end\n```\n\nEnsure that this interface is included in your bridging header. You can now use the \nfollowing pattern in your Swift code:\n\n```swift\nlet foo = Foo()\nfoo.myPromise.then { (obj: AnyObject?) -> Int in\n    // it is not necessary to specify the type of `obj`\n    // we just do that for demonstrative purposes\n}\n```\n\n---\n\nLet’s say you have:\n\n```swift\n@objc class Foo: NSObject {\n    func stringPromise() -> Promise<String>    \n    func barPromise() -> Promise<Bar>\n}\n\n@objc class Bar: NSObject { /*…*/ }\n```\n\nEnsure that your project is generating a `…-Swift.h` header so that Objective-C can see your Swift code.\n\nIf you built this project and opened the `…-Swift.h` header, you would only see this:\n\n```objc\n@interface Foo\n@end\n\n@interface Bar\n@end\n```\n\nThat's because Objective-C cannot import Swift objects that are generic. So we need to write some stubs:\n\n```swift\n@objc class Foo: NSObject {\n    @objc func stringPromise() -> AnyPromise {\n        return AnyPromise(stringPromise())\n    }\n    @objc func barPromise() -> AnyPromise {\n        return AnyPromise(barPromise())\n    }\n}\n```\n\nIf we built this and opened our generated header, we would now see:\n\n```objc\n@interface Foo\n- (AnyPromise *)stringPromise;\n- (AnyPromise *)barPromise;\n@end\n\n@interface Bar\n@end\n```\n\nPerfect.\n\nNote that AnyPromise can only bridge objects that conform to `AnyObject` or derive from `NSObject`. This is a limitation of Objective-C.\n\n# Using ObjC AnyPromises from Swift\n\nSimply use them, the type of your handler parameter is `Any`:\n\n```objective-c\n- (AnyPromise *)fetchThings {\n    return [AnyPromise promiseWithValue:@[@\"a\", @\"b\", @\"c\"]];\n}\n```\n\nSince ObjC is not type-safe and Swift is, you will (probably) need to cast the `Any` to whatever it is you actually are feeding:\n\n```swift\nFoo.fetchThings().done { any in\n    let bar = any as! [String]\n}\n```\n\n## :warning: Caution:\n\nARC in Objective-C, unlike in Objective-C++, is not exception-safe by default.\nSo, throwing an error will result in keeping a strong reference to the closure \nthat contains the throw statement.\nThis pattern will consequently result in memory leaks if you're not careful.\n\n> *Note:* Only having a strong reference to the closure would result in memory leaks.\n> In our case, PromiseKit automatically keeps a strong reference to the closure until it's released.\n\n__Workarounds:__\n\n1. Return a Promise with value NSError\\\nInstead of throwing a normal error, you can return a Promise with value NSError instead.\n\n```objc\nmyPromise.then(^{\n    return [AnyPromise promiseWithValue:[NSError myCustomError]];\n}).catch(^(NSError *error){\n    if ([error isEqual:[NSError myCustomError]]) {\n        // In case, same error as the one we thrown\n        return;\n    }\n    //…\n});\n```\n2. Enable ARC for exceptions in Objective-C (not recommended)\\\nYou can add this  ```-fobjc-arc-exceptions to your``` to your compiler flags to enable ARC for exceptions.\nThis is not recommended unless you've read the Apple documentation and are comfortable with the caveats.\n\nFor more details on ARC and exceptions:\nhttps://clang.llvm.org/docs/AutomaticReferenceCounting.html#exceptions\n\n"
  },
  {
    "path": "Documentation/README.md",
    "content": "# Contents\n\n* [README](../README.md)\n* Handbook\n  * [Getting Started](GettingStarted.md)\n  * [Promises: Common Patterns](CommonPatterns.md)\n  * [Frequently Asked Questions](FAQ.md)\n* Manual\n  * [Installation Guide](Installation.md)\n  * [Objective-C Guide](ObjectiveC.md)\n  * [Troubleshooting](Troubleshooting.md)\n  * [Appendix](Appendix.md)\n* [Examples](Examples)\n* [API Reference](https://mxcl.dev/PromiseKit/reference/v6/Classes/Promise.html)\n"
  },
  {
    "path": "Documentation/Troubleshooting.md",
    "content": "# Troubleshooting\n\n## Compilation errors\n\n99% of compilation issues involving PromiseKit can be addressed or diagnosed by one of the fixes below.\n\n### Check your handler\n\n```swift\nreturn firstly {\n      URLSession.shared.dataTask(.promise, with: url)\n}.compactMap {\n    JSONSerialization.jsonObject(with: $0.data) as? [String: Any]\n}.then { dict in\n    User(dict: dict)\n}\n```\n\nSwift (unhelpfully) says:\n\n> Cannot convert value of type '([String : Any]) -> User' to expected argument type '([String : Any]) -> _'\n\nWhat’s the real problem? `then` *must* return a `Promise`, and you're trying to return something else. What you really want is `map`:\n\n```swift\nreturn firstly {\n      URLSession.shared.dataTask(.promise, with: url)\n}.compactMap {\n    JSONSerialization.jsonObject(with: $0.data) as? [String: Any]\n}.map { dict in\n    User(dict: dict)\n}\n```\n\n### Specify closure parameters **and** return type\n\nFor example:\n\n```swift\nreturn firstly {\n    foo()\n}.then { user in\n    //…\n    return bar()\n}\n```\n\nThis code may compile if you specify the type of `user`:\n\n\n```swift\nreturn firstly {\n    foo()\n}.then { (user: User) in\n    //…\n    return bar()\n}\n```\n\nIf it still doesn't compile, perhaps you need to specify the return type, too:\n\n```swift\nreturn firstly {\n    foo()\n}.then { (user: User) -> Promise<Bar> in\n    //…\n    return bar()\n}\n```\n\nWe have made great effort to reduce the need for explicit typing in PromiseKit 6, \nbut as with all Swift functions that return a generic type (e.g., `Array.map`),\nyou may need to explicitly tell Swift what a closure returns if the closure's body is\nlonger than one line.\n\n> *Tip*: Sometimes you can force a one-liner by using semicolons.\n\n\n### Acknowledge all incoming closure parameters\n\nSwift does not permit you to silently ignore a closure's parameters. For example, this code:\n\n```swift\nfunc _() -> Promise<Void> {\n    return firstly {\n        proc.launch(.promise)      // proc: Foundation.Process\n    }.then {\n        when(fulfilled: p1, p2)    // both p1 & p2 are `Promise<Void>`\n    }\n}\n```\n\nFails to compile with the error:\n\n    Cannot invoke 'then' with an argument list of type '(() -> _)\n  \nWhat's the problem? Well, `Process.launch(.promise)` returns\n`Promise<(String, String)>`, and we are ignoring this value in our `then` closure. \nIf we’d referenced `$0` or named the parameter, Swift would have been satisfied.\n\nAssuming that we really do want to ignore the argument, the fix is to explicitly\nacknowledge its existence by assigning it the name \"_\". That's Swift-ese for \"I\nknow there's a value here, but I'm ignoring it.\"\n\n\n```swift\nfunc _() -> Promise<Void> {\n    return firstly {\n        proc.launch(.promise)\n    }.then { _ in\n        when(fulfilled: p1, p2)\n    }\n}\n```\n\nIn this situation, you won't always receive an error message that's as clear as the\none shown above. Sometimes, a missing closure parameter sends Swift scurrying off\ninto type inference limbo. When it finally concludes that there's no way for it to make\nall the inferred types work together, it may end up assigning blame to some other\nclosure entirely and giving you an error message that makes no sense at all.\n\nWhen faced with this kind of enigmatic complaint, a good rule of thumb is to\ndouble-check your argument and return types carefully. If everything looks OK, \ntemporarily add explicit type information as shown above, just to rule\nout misinference as a possible cause.\n\n### Try moving code to a temporary inline function\n\nTry taking the code out of a closure and putting it in a standalone function. Now Swift\nwill give you the *real* error message. For example:\n\n```swift\nfunc doStuff() {\n    firstly {\n        foo()\n    }.then {\n        let bar = bar()\n        let baz = baz()\n        when(fulfilled: bar, baz)\n    }\n}\n```\n\nBecomes:\n\n```swift\nfunc doStuff() {\n    func fluff() -> Promise<…> {\n        let bar = bar()\n        let baz = baz()\n        when(fulfilled: bar, baz)  \n    }\n\n    firstly {\n        foo()\n    }.then {\n        fluff()\n    }\n}\n```\n\nAn *inline* function like this is all you need. Here, the problem is that you\nforgot to mark the last line of the closure with an explicit `return`. It's required\nhere because the closure is longer than one line.\n\n\n## You copied code off the Internet that doesn’t work\n\nSwift has changed a lot over the years and so PromiseKit has had to change to keep\nup. The code you copied is probably for an older PromiseKit. *Read the definitions of the\nfunctions.* It's easy to do this in Xcode by option-clicking or command-clicking function names.\nAll PromiseKit functions are documented and provide examples.\n\n## \"Context type for closure argument expects 1 argument, which cannot be implicitly ignored\"\n\nYou have a `then`; you want a `done`.\n\n## \"Missing argument for parameter #1 in call\"\n\nThis is part of Swift 4’s “tuplegate”.\n\nYou must specify your `Void` parameter:\n\n```swift\nseal.fulfill(())\n```\n\nYes: we hope they revert this change in Swift 5 too.\n\n## \"Ambiguous reference to 'firstly(execute:)'\"\n\nRemove the firstly, e.g.:\n\n```swift\nfirstly {\n    foo()\n}.then {\n    //…\n}\n```\n\nbecomes: \n\n```swift\nfoo().then {\n    //…\n}\n```\n\nRebuild and Swift should now tell you the *real* error.\n\n## Other issues\n\n### `Pending Promise Deallocated!`\n\nIf you see this warning, you have a path in your `Promise` initializer that allows\nthe promise to escape without being sealed:\n\n```swift\nPromise<String> { seal in\n    task { value, error in\n        if let value = value as? String {\n            seal.fulfill(value)\n        } else if let error = error {\n            seal.reject(error)\n        }\n    }\n}\n```\n\nThere are two missing paths here, and if either occurs, the promise will soon be\ndeallocated without resolving. This will manifest itself as a bug in your app,\nprobably the awful infinite spinner.\n\nSo let’s be thorough:\n\n```swift\nPromise<String> { seal in\n    task { value, error in\n        if let value = value as? String {\n            fulfill(value)\n        } else if let error = error {\n            reject(error)\n        } else if value != nil {\n            reject(MyError.valueNotString)\n        } else {\n            // should never happen, but we have an `PMKError` for task being called with `nil`, `nil`\n            reject(PMKError.invalidCallingConvention)\n        }\n    }\n}\n```\n\nIf this seems tedious, it shouldn’t. You would have to be this thorough without promises, too.\nThe difference is that without promises, you wouldn’t get a warning in the console notifying\nyou of your mistake!\n\n### Slow compilation / compiler cannot solve in reasonable time\n\nAdd return types to your closures.\n\n### My promise never resolves\n\nThere are several potential causes:\n\n#### 1. Check to be sure that your asynchronous task even *starts*\n\nYou’d be surprised how often this is the cause.\n\nFor example, if you are using `URLSession` without our extension (but\ndon’t do that; *use* our extension! we know all the pitfalls), did you forget\nto call `resume` on the task? If so, the task never actually starts, and so of\ncourse it never finishes, either.\n\n#### 2. Check that all paths in your custom Promise initializers are handled\n\nSee “Pending Promise Deallocated” above. Usually you will see this warning if\nyou are not handling a path, but that requires your promise deallocate, so you\nmay not see this warning yet you are still not handling all paths.\n\nUnhandled paths mean the promise will not resolve.\n\n#### 3. Ensure the queue your promise handler runs upon is not blocked\n\nIf the thread is blocked the handlers cannot execute. Commonly you can see this\nif you are using our `wait()` function. Please read the documentation for `wait()`\nfor suggestions and caveats.\n\n#### 4. Your promise returned a cancellation error\n\nCancelation is neither success nor failure. So this is the correct behavior. \nUse a `finally` if you need to do some clean up.\n\n### `Result of call to 'done(on:_:)' is unused`, `Result of call to 'then(on:_:)' is unused`\n\nPromiseKit deliberately avoids the `@discardableResult` annotation because the\nunused result warning is a hint that you have not handled the error in your\nchain. So do one of these:\n\n1. Add a `catch`\n2. `return` the promise (thus punting the error handling to the caller)\n3. Use `cauterize()` to silence the warning.\n\nObviously, do 1 or 2 in preference to 3.\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright 2016-present, Max Howell; mxcl@me.com\n\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "Package.swift",
    "content": "// swift-tools-version:4.0\n\nimport PackageDescription\n\nlet pkg = Package(name: \"PromiseKit\")\npkg.products = [\n    .library(name: \"PromiseKit\", targets: [\"PromiseKit\"]),\n]\n\nlet pmk: Target = .target(name: \"PromiseKit\")\npmk.path = \"Sources\"\npmk.exclude = [\n    \"AnyPromise.swift\",\n    \"AnyPromise.m\",\n    \"PMKCallVariadicBlock.m\",\n    \"dispatch_promise.m\",\n    \"join.m\",\n    \"when.m\",\n    \"NSMethodSignatureForBlock.m\",\n    \"after.m\",\n    \"hang.m\",\n    \"race.m\",\n    \"Deprecations.swift\"\n]\npkg.swiftLanguageVersions = [3, 4, 5]\npkg.targets = [\n    pmk,\n    .testTarget(name: \"APlus\", dependencies: [\"PromiseKit\"], path: \"Tests/A+\"),\n    .testTarget(name: \"CorePromise\", dependencies: [\"PromiseKit\"], path: \"Tests/CorePromise\"),\n]\n"
  },
  {
    "path": "Package@swift-4.2.swift",
    "content": "// swift-tools-version:4.2\n\nimport PackageDescription\n\nlet pkg = Package(name: \"PromiseKit\")\npkg.products = [\n    .library(name: \"PromiseKit\", targets: [\"PromiseKit\"]),\n]\n\nlet pmk: Target = .target(name: \"PromiseKit\")\npmk.path = \"Sources\"\npmk.exclude = [\n    \"AnyPromise.swift\",\n    \"AnyPromise.m\",\n    \"PMKCallVariadicBlock.m\",\n    \"dispatch_promise.m\",\n    \"join.m\",\n    \"when.m\",\n    \"NSMethodSignatureForBlock.m\",\n    \"after.m\",\n    \"hang.m\",\n    \"race.m\",\n    \"Deprecations.swift\"\n]\npkg.swiftLanguageVersions = [.v3, .v4, .v4_2]\npkg.targets = [\n    pmk,\n    .testTarget(name: \"APlus\", dependencies: [\"PromiseKit\"], path: \"Tests/A+\"),\n    .testTarget(name: \"CorePromise\", dependencies: [\"PromiseKit\"], path: \"Tests/CorePromise\"),\n]\n"
  },
  {
    "path": "Package@swift-5.0.swift",
    "content": "// swift-tools-version:5.0\n\nimport PackageDescription\n\nlet pkg = Package(name: \"PromiseKit\")\npkg.platforms = [\n   .macOS(.v10_10), .iOS(.v8), .tvOS(.v9), .watchOS(.v2)\n]\npkg.products = [\n    .library(name: \"PromiseKit\", targets: [\"PromiseKit\"]),\n]\n\nlet pmk: Target = .target(name: \"PromiseKit\")\npmk.path = \"Sources\"\npmk.exclude = [\n    \"AnyPromise.swift\",\n    \"AnyPromise.m\",\n    \"PMKCallVariadicBlock.m\",\n    \"dispatch_promise.m\",\n    \"join.m\",\n    \"when.m\",\n    \"NSMethodSignatureForBlock.m\",\n    \"after.m\",\n    \"hang.m\",\n    \"race.m\",\n    \"Deprecations.swift\"\n]\npkg.swiftLanguageVersions = [.v4, .v4_2, .v5]\npkg.targets = [\n    pmk,\n    .testTarget(name: \"APlus\", dependencies: [\"PromiseKit\"], path: \"Tests/A+\"),\n    .testTarget(name: \"CorePromise\", dependencies: [\"PromiseKit\"], path: \"Tests/CorePromise\"),\n]\n"
  },
  {
    "path": "Package@swift-5.3.swift",
    "content": "// swift-tools-version:5.3\n\nimport PackageDescription\n\nlet pkg = Package(name: \"PromiseKit\")\npkg.platforms = [\n   .macOS(.v10_10), .iOS(.v9), .tvOS(.v9), .watchOS(.v2)\n]\npkg.products = [\n    .library(name: \"PromiseKit\", targets: [\"PromiseKit\"]),\n]\n\nlet pmk: Target = .target(name: \"PromiseKit\")\npmk.path = \"Sources\"\npmk.resources = [\n    .process(\"Resources/PrivacyInfo.xcprivacy\")\n]\npmk.exclude = [\n    \"AnyPromise.swift\",\n    \"AnyPromise.m\",\n    \"PMKCallVariadicBlock.m\",\n    \"dispatch_promise.m\",\n    \"join.m\",\n    \"when.m\",\n    \"NSMethodSignatureForBlock.m\",\n    \"after.m\",\n    \"hang.m\",\n    \"race.m\",\n    \"Deprecations.swift\",\n    \"Info.plist\"\n]\npkg.swiftLanguageVersions = [.v4, .v4_2, .v5]\npkg.targets = [\n    pmk,\n    .testTarget(name: \"APlus\", dependencies: [\"PromiseKit\"], path: \"Tests/A+\", exclude: [\"README.md\"]),\n    .testTarget(name: \"CorePromise\", dependencies: [\"PromiseKit\"], path: \"Tests/CorePromise\"),\n]\n"
  },
  {
    "path": "PromiseKit.playground/Contents.swift",
    "content": "import PlaygroundSupport\n\n// Is this erroring? If so open the `.xcodeproj` and build the\n// framework for a macOS target (usually labeled: “My Mac”).\n// Then select `PromiseKit.playground` from inside Xcode.\nimport PromiseKit\n\n\nfunc promise3() -> Promise<Int> {\n    return after(.seconds(1)).map{ 3 }\n}\n\nfirstly {\n    Promise.value(1)\n}.map { _ in\n    2\n}.then { _ in\n    promise3()\n}.done {\n    print($0)  // => 3\n}.catch { error in\n    // only happens for errors\n}.finally {\n    PlaygroundPage.current.finishExecution()\n}\n\nPlaygroundPage.current.needsIndefiniteExecution = true\n"
  },
  {
    "path": "PromiseKit.playground/contents.xcplayground",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='3.0' sdk='macosx' auto-termination-delay='2'>\n    <sections>\n        <code source-file-name='section-1.swift'/>\n    </sections>\n    <timeline fileName='timeline.xctimeline'/>\n</playground>"
  },
  {
    "path": "PromiseKit.playground/playground.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "PromiseKit.podspec",
    "content": "Pod::Spec.new do |s|\n  s.name = \"PromiseKit\"\n\n  s.version = '8.2.0'\n\n  s.source = {\n    :git => \"https://github.com/mxcl/#{s.name}.git\",\n    :tag => s.version,\n    :submodules => true\n  }\n\n  s.license = 'MIT'\n  s.summary = 'Promises for Swift & ObjC.'\n  s.homepage = 'http://mxcl.dev/PromiseKit/'\n  s.description = 'A thoughtful and complete implementation of promises for iOS, macOS, watchOS and tvOS with first-class support for both Objective-C and Swift.'\n  s.social_media_url = 'https://twitter.com/mxcl'\n  s.authors  = { 'Max Howell' => 'mxcl@me.com' }\n  s.documentation_url = 'http://mxcl.dev/PromiseKit/reference/v6/Classes/Promise.html'\n  s.default_subspecs = 'CorePromise', 'UIKit', 'Foundation'\n  s.requires_arc = true\n\n  s.swift_version = '3.2', '3.3', '3.4', '4.0', '4.1', '4.2', '4.3', '4.4', '5.0', '5.1', '5.2', '5.3', '5.4', '5.5'\n\n  # CocoaPods requires us to specify the root deployment targets\n  # even though for us it is nonsense. Our root spec has no\n  # sources.\n  s.ios.deployment_target = '10.0'\n  s.osx.deployment_target = '10.13'\n  s.watchos.deployment_target = '4.0'\n  s.tvos.deployment_target = '10.0'\n  s.visionos.deployment_target = '1.0'\n\n  s.pod_target_xcconfig = {\n    'OTHER_SWIFT_FLAGS' => '-DPMKCocoaPods',\n  }\n\n  s.resource_bundles = {\n    'PromiseKit_Privacy' => 'Sources/Resources/PrivacyInfo.xcprivacy'\n  }\n\n  s.subspec 'Accounts' do |ss|\n    ss.ios.source_files = ss.osx.source_files = 'Extensions/Accounts/Sources/**/*'\n    ss.exclude_files = 'Extensions/Accounts/Sources/*.plist'\n    ss.ios.frameworks = ss.osx.frameworks = 'Accounts'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.ios.deployment_target = '10.0'\n    ss.osx.deployment_target = '10.13'\n  end\n\n  s.subspec 'AddressBook' do |ss|\n    ss.ios.source_files = 'Extensions/AddressBook/Sources/**/*'\n    ss.exclude_files = 'Extensions/AddressBook/Sources/*.plist'\n    ss.ios.frameworks = 'AddressBook'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.ios.deployment_target = '10.0'\n  end\n\n  s.subspec 'AssetsLibrary' do |ss|\n    ss.ios.source_files = 'Extensions/AssetsLibrary/Sources/**/*'\n    ss.exclude_files = 'Extensions/AssetsLibrary/Sources/*.plist'\n    ss.ios.frameworks = 'AssetsLibrary'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.ios.deployment_target = '10.0'\n  end\n\n  s.subspec 'AVFoundation' do |ss|\n    ss.ios.source_files = 'Extensions/AVFoundation/Sources/**/*'\n    ss.exclude_files = 'Extensions/AVFoundation/Sources/*.plist'\n    ss.ios.frameworks = 'AVFoundation'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.ios.deployment_target = '10.0'\n  end\n\n  s.subspec 'CloudKit' do |ss|\n    ss.source_files = 'Extensions/CloudKit/Sources/**/*'\n    ss.exclude_files = 'Extensions/CloudKit/Sources/*.plist'\n    ss.frameworks = 'CloudKit'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.ios.deployment_target = '10.0'\n    ss.osx.deployment_target = '10.13'\n    ss.tvos.deployment_target = '10.0'\n    ss.watchos.deployment_target = '4.0'\n  end\n\n  s.subspec 'CoreBluetooth' do |ss|\n    ss.ios.source_files = ss.osx.source_files = ss.tvos.source_files = 'Extensions/CoreBluetooth/Sources/**/*'\n    ss.exclude_files = 'Extensions/CoreBluetooth/Sources/*.plist'\n    ss.ios.frameworks = ss.osx.frameworks = ss.tvos.frameworks = 'CoreBluetooth'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.ios.deployment_target = '10.0'\n    ss.osx.deployment_target = '10.13'\n    ss.tvos.deployment_target = '10.0'\n  end\n\n  s.subspec 'CorePromise' do |ss|\n    hh = Dir['Sources/*.h'] - Dir['Sources/*+Private.h']\n\n    cc = Dir['Sources/*.swift'] - ['Sources/SwiftPM.swift']\n    cc << 'Sources/{after,AnyPromise,GlobalState,dispatch_promise,hang,join,PMKPromise,when,race}.m'\n    cc += hh\n\n    ss.source_files = cc\n    ss.exclude_files = 'Sources/*.plist'\n    ss.public_header_files = hh\n    ss.preserve_paths = 'Sources/AnyPromise+Private.h', 'Sources/PMKCallVariadicBlock.m', 'Sources/NSMethodSignatureForBlock.m'\n    ss.frameworks = 'Foundation'\n\n    ss.ios.deployment_target = '10.0'\n    ss.osx.deployment_target = '10.13'\n    ss.watchos.deployment_target = '4.0'\n    ss.tvos.deployment_target = '10.0'\n  end\n\n  s.subspec 'CoreLocation' do |ss|\n    ss.source_files = 'Extensions/CoreLocation/Sources/**/*'\n    ss.exclude_files = 'Extensions/CoreLocation/Sources/*.plist'\n    ss.watchos.source_files = 'Extensions/CoreLocation/Sources/CLGeocoder*'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.frameworks = 'CoreLocation'\n\n    ss.ios.deployment_target = '10.0'\n    ss.osx.deployment_target = '10.13'\n    ss.watchos.deployment_target = '4.0'\n    ss.tvos.deployment_target = '10.0'\n  end\n\n  s.subspec 'EventKit' do |ss|\n    ss.ios.source_files = ss.osx.source_files = ss.watchos.source_files = 'Extensions/EventKit/Sources/**/*'\n    ss.exclude_files = 'Extensions/EventKit/Sources/*.plist'\n    ss.ios.frameworks = ss.osx.frameworks = ss.watchos.frameworks = 'EventKit'\n    ss.dependency 'PromiseKit/CorePromise'\n\n    ss.ios.deployment_target = '10.0'\n    ss.osx.deployment_target = '10.13'\n    ss.watchos.deployment_target = '4.0'\n  end\n\n  s.subspec 'Foundation' do |ss|\n    ss.source_files = Dir['Extensions/Foundation/Sources/**/*']\n    ss.exclude_files = 'Extensions/Foundation/Sources/*.plist'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.frameworks = 'Foundation'\n    ss.ios.deployment_target = '10.0'\n    ss.osx.deployment_target = '10.13'\n    ss.watchos.deployment_target = '4.0'\n    ss.tvos.deployment_target = '10.0'\n  end\n\n  s.subspec 'HealthKit' do |ss|\n    ss.source_files = Dir['Extensions/HealthKit/Sources/**/*']\n    ss.exclude_files = 'Extensions/HealthKit/Sources/*.plist'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.frameworks = 'HealthKit'\n    ss.ios.deployment_target = '10.0'\n    ss.watchos.deployment_target = '4.0'\n  end\n\n  s.subspec 'HomeKit' do |ss|\n    ss.source_files = Dir['Extensions/HomeKit/Sources/**/*']\n    ss.exclude_files = 'Extensions/HomeKit/Sources/*.plist'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.frameworks = 'HomeKit'\n    ss.ios.deployment_target = '10.0'\n    ss.watchos.deployment_target = '4.0'\n    ss.tvos.deployment_target = '10.0'\n  end\n\n  s.subspec 'MapKit' do |ss|\n    ss.ios.source_files = ss.osx.source_files = ss.tvos.source_files = 'Extensions/MapKit/Sources/**/*'\n    ss.exclude_files = 'Extensions/MapKit/Sources/*.plist'\n    ss.ios.frameworks = ss.osx.frameworks = ss.tvos.frameworks = 'MapKit'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.ios.deployment_target = '10.0'\n    ss.osx.deployment_target = '10.13'\n    ss.watchos.deployment_target = '4.0'\n    ss.tvos.deployment_target = '10.0'\n  end\n\n  s.subspec 'MessageUI' do |ss|\n    ss.ios.source_files = 'Extensions/MessagesUI/Sources/**/*'\n    ss.exclude_files = 'Extensions/MessagesUI/Sources/*.plist'\n    ss.ios.frameworks = 'MessageUI'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.ios.deployment_target = '10.0'\n  end\n\n  s.subspec 'Photos' do |ss|\n    ss.ios.source_files = ss.tvos.source_files = ss.osx.source_files = 'Extensions/Photos/Sources/**/*'\n    ss.exclude_files = 'Extensions/Photos/Sources/*.plist'\n    ss.ios.frameworks = ss.tvos.frameworks = ss.osx.frameworks = 'Photos'\n    ss.dependency 'PromiseKit/CorePromise'\n\n    ss.ios.deployment_target = '10.0'\n    ss.osx.deployment_target = '10.13'\n    ss.tvos.deployment_target = '10.0'\n  end\n\n  s.subspec 'QuartzCore' do |ss|\n    ss.osx.source_files = ss.ios.source_files = ss.tvos.source_files = 'Extensions/QuartzCore/Sources/**/*'\n    ss.exclude_files = 'Extensions/QuartzCore/Sources/*.plist'\n    ss.osx.frameworks = ss.ios.frameworks = ss.tvos.frameworks = 'QuartzCore'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.ios.deployment_target = '10.0'\n    ss.osx.deployment_target = '10.13'\n    ss.tvos.deployment_target = '10.0'\n  end\n\n  s.subspec 'Social' do |ss|\n    ss.ios.source_files = 'Extensions/Social/Sources/**/*'\n    ss.exclude_files = 'Extensions/Social/Sources/*.plist'\n    ss.osx.source_files = Dir['Extensions/Social/Sources/*'] - ['Categories/Social/Sources/*SLComposeViewController+Promise.swift']\n    ss.ios.frameworks = ss.osx.frameworks = 'Social'\n    ss.dependency 'PromiseKit/Foundation'\n    ss.ios.deployment_target = '10.0'\n    ss.osx.deployment_target = '10.13'\n  end\n\n  s.subspec 'StoreKit' do |ss|\n    ss.ios.source_files = ss.osx.source_files = ss.tvos.source_files = 'Extensions/StoreKit/Sources/**/*'\n    ss.exclude_files = 'Extensions/StoreKit/Sources/*.plist'\n    ss.ios.frameworks = ss.osx.frameworks = ss.tvos.frameworks = 'StoreKit'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.ios.deployment_target = '10.0'\n    ss.osx.deployment_target = '10.13'\n    ss.tvos.deployment_target = '10.0'\n  end\n\n  s.subspec 'SystemConfiguration' do |ss|\n    ss.ios.source_files = ss.osx.source_files = ss.tvos.source_files = 'Extensions/SystemConfiguration/Sources/**/*'\n    ss.exclude_files = 'Extensions/SystemConfiguration/Sources/*.plist'\n    ss.ios.frameworks = ss.osx.frameworks = ss.tvos.frameworks = 'SystemConfiguration'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.ios.deployment_target = '10.0'\n    ss.osx.deployment_target = '10.13'\n    ss.tvos.deployment_target = '10.0'\n  end\n\n  picker_cc = 'Extensions/UIKit/Sources/UIImagePickerController+Promise.swift'\n\n  s.subspec 'UIKit' do |ss|\n    ss.ios.source_files = ss.tvos.source_files = Dir['Extensions/UIKit/Sources/**/*'] - [picker_cc]\n    ss.exclude_files = 'Extensions/UIKit/Sources/*.plist'\n    ss.tvos.frameworks = ss.ios.frameworks = 'UIKit'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.ios.deployment_target = '10.0'\n    ss.tvos.deployment_target = '10.0'\n  end\n\n  s.subspec 'UIImagePickerController' do |ss|\n    # Since iOS 10, App Store submissions that contain references to\n    # UIImagePickerController (even if unused in 3rd party libraries)\n    # are rejected unless an Info.plist key is specified, thus we\n    # moved this code to a sub-subspec.\n    #\n    # This *was* a subspec of UIKit, but bizarrely CocoaPods would\n    # include this when specifying *just* UIKit…!\n\n    ss.ios.source_files = picker_cc\n    ss.exclude_files = 'Extensions/UIKit/Sources/*.plist'\n    ss.ios.frameworks = 'UIKit'\n    ss.ios.xcconfig = { \"GCC_PREPROCESSOR_DEFINITIONS\" => '$(inherited) PMKImagePickerController=1' }\n    ss.dependency 'PromiseKit/UIKit'\n    ss.ios.deployment_target = '10.0'\n  end\n\n  s.subspec 'WatchConnectivity' do |ss|\n    ss.ios.source_files = ss.watchos.source_files = 'Extensions/WatchConnectivity/Sources/**/*'\n    ss.exclude_files = 'Extensions/WatchConnectivity/Sources/*.plist'\n    ss.ios.frameworks = ss.watchos.frameworks = 'WatchConnectivity'\n    ss.dependency 'PromiseKit/CorePromise'\n    ss.ios.deployment_target = '10.0'\n    ss.watchos.deployment_target = '4.0'\n  end\nend\n"
  },
  {
    "path": "PromiseKit.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t085B96B321A6359500E5E22F /* LoggingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 085B96B121A6358900E5E22F /* LoggingTests.swift */; };\n\t\t085B96BF21A9B37C00E5E22F /* LogEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 085B96BE21A9B37C00E5E22F /* LogEvent.swift */; };\n\t\t0C42F31B1FCF86320051309C /* HangTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C42F3191FCF86240051309C /* HangTests.swift */; };\n\t\t0CC3AF2B1FCF84F7000E98C9 /* hang.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CC3AF2A1FCF84F7000E98C9 /* hang.swift */; };\n\t\t49A5584D1DC5185900E4D01B /* ResolverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A5584B1DC5172F00E4D01B /* ResolverTests.swift */; };\n\t\t630A8056203CEF6800D25F23 /* AnyPromiseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 630A8051203CEF6800D25F23 /* AnyPromiseTests.m */; settings = {COMPILER_FLAGS = \"-fobjc-arc-exceptions\"; }; };\n\t\t630A8057203CEF6800D25F23 /* PMKManifoldTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 630A8052203CEF6800D25F23 /* PMKManifoldTests.m */; };\n\t\t630A8058203CEF6800D25F23 /* JoinTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 630A8053203CEF6800D25F23 /* JoinTests.m */; };\n\t\t630A8059203CEF6800D25F23 /* HangTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 630A8054203CEF6800D25F23 /* HangTests.m */; };\n\t\t630A805A203CEF6800D25F23 /* WhenTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 630A8055203CEF6800D25F23 /* WhenTests.m */; };\n\t\t630A805B203CF67800D25F23 /* DefaultDispatchQueueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 635D641B1D59635300BC0AF5 /* DefaultDispatchQueueTests.swift */; };\n\t\t631411381D59795700E24B9E /* PromiseKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63B0AC571D595E1B00FA21D9 /* PromiseKit.framework */; };\n\t\t631411431D59797100E24B9E /* BridgingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6314113E1D59797100E24B9E /* BridgingTests.m */; };\n\t\t631411441D59797100E24B9E /* BridgingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6314113F1D59797100E24B9E /* BridgingTests.swift */; };\n\t\t631411451D59797100E24B9E /* Infrastructure.m in Sources */ = {isa = PBXBuildFile; fileRef = 631411411D59797100E24B9E /* Infrastructure.m */; };\n\t\t631411461D59797100E24B9E /* Infrastructure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631411421D59797100E24B9E /* Infrastructure.swift */; };\n\t\t631751A41D59766500A9DDDC /* PromiseKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63B0AC571D595E1B00FA21D9 /* PromiseKit.framework */; };\n\t\t631751B71D59768200A9DDDC /* 0.0.0.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631751AB1D59768200A9DDDC /* 0.0.0.swift */; };\n\t\t631751B81D59768200A9DDDC /* 2.1.2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631751AC1D59768200A9DDDC /* 2.1.2.swift */; };\n\t\t631751B91D59768200A9DDDC /* 2.1.3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631751AD1D59768200A9DDDC /* 2.1.3.swift */; };\n\t\t631751BA1D59768200A9DDDC /* 2.2.2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631751AE1D59768200A9DDDC /* 2.2.2.swift */; };\n\t\t631751BB1D59768200A9DDDC /* 2.2.3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631751AF1D59768200A9DDDC /* 2.2.3.swift */; };\n\t\t631751BC1D59768200A9DDDC /* 2.2.4.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631751B01D59768200A9DDDC /* 2.2.4.swift */; };\n\t\t631751BD1D59768200A9DDDC /* 2.2.6.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631751B11D59768200A9DDDC /* 2.2.6.swift */; };\n\t\t631751BE1D59768200A9DDDC /* 2.2.7.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631751B21D59768200A9DDDC /* 2.2.7.swift */; };\n\t\t631751BF1D59768200A9DDDC /* 2.3.1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631751B31D59768200A9DDDC /* 2.3.1.swift */; };\n\t\t631751C01D59768200A9DDDC /* 2.3.2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631751B41D59768200A9DDDC /* 2.3.2.swift */; };\n\t\t631751C11D59768200A9DDDC /* 2.3.4.swift in Sources */ = {isa = PBXBuildFile; fileRef = 631751B51D59768200A9DDDC /* 2.3.4.swift */; };\n\t\t632FBBE31F33B273008F8FBB /* Catchable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 632FBBE21F33B273008F8FBB /* Catchable.swift */; };\n\t\t632FBBE51F33B338008F8FBB /* CatchableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 632FBBE41F33B338008F8FBB /* CatchableTests.swift */; };\n\t\t633027E6203CC0060037E136 /* PromiseKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63B0AC571D595E1B00FA21D9 /* PromiseKit.framework */; };\n\t\t6330B5E11F2E991200D60528 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6330B5E01F2E991200D60528 /* Configuration.swift */; };\n\t\t634AAD2B1EAE517C00B17855 /* fwd.h in Headers */ = {isa = PBXBuildFile; fileRef = 634AAD2A1EAE517C00B17855 /* fwd.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t635D641D1D59635300BC0AF5 /* PromiseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 635D64081D59635300BC0AF5 /* PromiseTests.swift */; };\n\t\t635D641E1D59635300BC0AF5 /* CancellableErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 635D64091D59635300BC0AF5 /* CancellableErrorTests.swift */; };\n\t\t635D64221D59635300BC0AF5 /* ZalgoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 635D640D1D59635300BC0AF5 /* ZalgoTests.swift */; };\n\t\t635D64231D59635300BC0AF5 /* AfterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 635D640E1D59635300BC0AF5 /* AfterTests.swift */; };\n\t\t635D64261D59635300BC0AF5 /* WhenResolvedTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 635D64111D59635300BC0AF5 /* WhenResolvedTests.swift */; };\n\t\t635D64271D59635300BC0AF5 /* RaceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 635D64121D59635300BC0AF5 /* RaceTests.swift */; };\n\t\t635D64281D59635300BC0AF5 /* WhenConcurrentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 635D64131D59635300BC0AF5 /* WhenConcurrentTests.swift */; };\n\t\t635D642A1D59635300BC0AF5 /* WhenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 635D64151D59635300BC0AF5 /* WhenTests.swift */; };\n\t\t635D642B1D59635300BC0AF5 /* StressTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 635D64161D59635300BC0AF5 /* StressTests.swift */; };\n\t\t635D642C1D59635300BC0AF5 /* RegressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 635D64171D59635300BC0AF5 /* RegressionTests.swift */; };\n\t\t635D64301D596E8500BC0AF5 /* PromiseKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63B0AC571D595E1B00FA21D9 /* PromiseKit.framework */; };\n\t\t636A291A1F1C156B001229C2 /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 636A29191F1C156B001229C2 /* Promise.swift */; };\n\t\t636A291F1F1C16FF001229C2 /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = 636A291E1F1C16FF001229C2 /* Box.swift */; };\n\t\t636A29211F1C1716001229C2 /* Thenable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 636A29201F1C1716001229C2 /* Thenable.swift */; };\n\t\t636A29231F1C17A6001229C2 /* Guarantee.swift in Sources */ = {isa = PBXBuildFile; fileRef = 636A29221F1C17A6001229C2 /* Guarantee.swift */; };\n\t\t636A29251F1C3089001229C2 /* race.swift in Sources */ = {isa = PBXBuildFile; fileRef = 636A29241F1C3089001229C2 /* race.swift */; };\n\t\t636A29271F1C3927001229C2 /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 636A29261F1C3927001229C2 /* Resolver.swift */; };\n\t\t639BF757203DF03100FA577B /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639BF755203DF02C00FA577B /* Utilities.swift */; };\n\t\t63B0AC7F1D595E6300FA21D9 /* after.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B0AC611D595E6300FA21D9 /* after.m */; };\n\t\t63B0AC801D595E6300FA21D9 /* after.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B0AC621D595E6300FA21D9 /* after.swift */; };\n\t\t63B0AC811D595E6300FA21D9 /* AnyPromise.h in Headers */ = {isa = PBXBuildFile; fileRef = 63B0AC631D595E6300FA21D9 /* AnyPromise.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t63B0AC821D595E6300FA21D9 /* AnyPromise.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B0AC641D595E6300FA21D9 /* AnyPromise.m */; };\n\t\t63B0AC831D595E6300FA21D9 /* AnyPromise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B0AC651D595E6300FA21D9 /* AnyPromise.swift */; };\n\t\t63B0AC841D595E6300FA21D9 /* AnyPromise+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 63B0AC661D595E6300FA21D9 /* AnyPromise+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };\n\t\t63B0AC851D595E6300FA21D9 /* dispatch_promise.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B0AC671D595E6300FA21D9 /* dispatch_promise.m */; };\n\t\t63B0AC871D595E6300FA21D9 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B0AC691D595E6300FA21D9 /* Error.swift */; };\n\t\t63B0AC891D595E6300FA21D9 /* hang.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B0AC6B1D595E6300FA21D9 /* hang.m */; };\n\t\t63B0AC8B1D595E6300FA21D9 /* join.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B0AC6D1D595E6300FA21D9 /* join.m */; };\n\t\t63B0AC931D595E6300FA21D9 /* PromiseKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 63B0AC761D595E6300FA21D9 /* PromiseKit.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t63B0AC991D595E6300FA21D9 /* when.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B0AC7C1D595E6300FA21D9 /* when.m */; };\n\t\t63B0AC9A1D595E6300FA21D9 /* when.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B0AC7D1D595E6300FA21D9 /* when.swift */; };\n\t\t63B18AEC1F2D205C00B79E37 /* CustomStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B18AEB1F2D205C00B79E37 /* CustomStringConvertible.swift */; };\n\t\t63B7C94B203E2B8200FBEC00 /* AnyPromiseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B7C94A203E2B8200FBEC00 /* AnyPromiseTests.swift */; };\n\t\t63B912AA1F1D7B1300D49110 /* firstly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B912A91F1D7B1300D49110 /* firstly.swift */; };\n\t\t63CF6D7A203CC66000EC8927 /* ErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63CF6D79203CC66000EC8927 /* ErrorTests.swift */; };\n\t\t63CF6D7C203CCDAB00EC8927 /* GuaranteeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63CF6D7B203CCDAB00EC8927 /* GuaranteeTests.swift */; };\n\t\t63CF6D7E203CD12700EC8927 /* DeprecationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63648C94203CB97400EBA011 /* DeprecationTests.swift */; };\n\t\t63CF6D80203CD19200EC8927 /* ThenableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63CF6D7F203CD19200EC8927 /* ThenableTests.swift */; };\n\t\t63D9B2EF203385FD0075C00B /* race.m in Sources */ = {isa = PBXBuildFile; fileRef = 63D9B2EE203385FD0075C00B /* race.m */; };\n\t\t63D9B2F120338D5D0075C00B /* Deprecations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63D9B2F020338D5D0075C00B /* Deprecations.swift */; };\n\t\t9E4170F9287D88C900A3B4B5 /* Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4170F8287D88C800A3B4B5 /* Async.swift */; };\n\t\t9E4170FC287D8DF900A3B4B5 /* AsyncTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4170FA287D8DBD00A3B4B5 /* AsyncTests.swift */; };\n\t\t9E66231626FE5A8C00FA25CB /* RaceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E66231526FE5A8C00FA25CB /* RaceTests.m */; };\n\t\t9EC774272991495C00803027 /* Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC774262991495C00803027 /* Combine.swift */; };\n\t\t9EC7742A2991498200803027 /* CombineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC774282991497900803027 /* CombineTests.swift */; };\n\t\tC013F7382048E3B6006B57B1 /* MockNodeEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C013F7372048E3B6006B57B1 /* MockNodeEnvironment.swift */; };\n\t\tC013F73A2049076A006B57B1 /* JSPromise.swift in Sources */ = {isa = PBXBuildFile; fileRef = C013F7392049076A006B57B1 /* JSPromise.swift */; };\n\t\tC013F73C20494291006B57B1 /* JSAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C013F73B20494291006B57B1 /* JSAdapter.swift */; };\n\t\tC013F740204E5064006B57B1 /* JSUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = C013F73F204E5063006B57B1 /* JSUtils.swift */; };\n\t\tC0244E5E2047A6CB00ACB4AC /* PromiseKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63B0AC571D595E1B00FA21D9 /* PromiseKit.framework */; };\n\t\tC0244E692047AC9F00ACB4AC /* AllTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0244E682047AC9F00ACB4AC /* AllTests.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t631411341D59795700E24B9E /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 6399A3721D595D9100D65233 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 63B0AC561D595E1B00FA21D9;\n\t\t\tremoteInfo = PromiseKit;\n\t\t};\n\t\t6317518D1D59766500A9DDDC /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 6399A3721D595D9100D65233 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 63B0AC561D595E1B00FA21D9;\n\t\t\tremoteInfo = PromiseKit;\n\t\t};\n\t\t633027E2203CC0060037E136 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 6399A3721D595D9100D65233 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 63B0AC561D595E1B00FA21D9;\n\t\t\tremoteInfo = PromiseKit;\n\t\t};\n\t\t635D64041D5962F900BC0AF5 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 6399A3721D595D9100D65233 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 63B0AC561D595E1B00FA21D9;\n\t\t\tremoteInfo = PromiseKit;\n\t\t};\n\t\tC0244E502047A6CB00ACB4AC /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 6399A3721D595D9100D65233 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 63B0AC561D595E1B00FA21D9;\n\t\t\tremoteInfo = PromiseKit;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\tC0244E6E2047AF0B00ACB4AC /* CopyFiles */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"\";\n\t\t\tdstSubfolderSpec = 7;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t085B96B121A6358900E5E22F /* LoggingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggingTests.swift; sourceTree = \"<group>\"; };\n\t\t085B96BE21A9B37C00E5E22F /* LogEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LogEvent.swift; path = Sources/LogEvent.swift; sourceTree = \"<group>\"; };\n\t\t0C42F3191FCF86240051309C /* HangTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HangTests.swift; sourceTree = \"<group>\"; };\n\t\t0CC3AF2A1FCF84F7000E98C9 /* hang.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = hang.swift; path = Sources/hang.swift; sourceTree = \"<group>\"; };\n\t\t1F1DCDF72A27AB6400E7A16B /* PromiseKit.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = PromiseKit.podspec; sourceTree = \"<group>\"; };\n\t\t49A5584B1DC5172F00E4D01B /* ResolverTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResolverTests.swift; sourceTree = \"<group>\"; };\n\t\t630019221D596292003B4E30 /* PMKCoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PMKCoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t630A8051203CEF6800D25F23 /* AnyPromiseTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnyPromiseTests.m; sourceTree = \"<group>\"; };\n\t\t630A8052203CEF6800D25F23 /* PMKManifoldTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PMKManifoldTests.m; sourceTree = \"<group>\"; };\n\t\t630A8053203CEF6800D25F23 /* JoinTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JoinTests.m; sourceTree = \"<group>\"; };\n\t\t630A8054203CEF6800D25F23 /* HangTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HangTests.m; sourceTree = \"<group>\"; };\n\t\t630A8055203CEF6800D25F23 /* WhenTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WhenTests.m; sourceTree = \"<group>\"; };\n\t\t6314113C1D59795700E24B9E /* PMKBridgeTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PMKBridgeTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t6314113E1D59797100E24B9E /* BridgingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BridgingTests.m; sourceTree = \"<group>\"; };\n\t\t6314113F1D59797100E24B9E /* BridgingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BridgingTests.swift; sourceTree = \"<group>\"; };\n\t\t631411401D59797100E24B9E /* Infrastructure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Infrastructure.h; sourceTree = \"<group>\"; };\n\t\t631411411D59797100E24B9E /* Infrastructure.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Infrastructure.m; sourceTree = \"<group>\"; };\n\t\t631411421D59797100E24B9E /* Infrastructure.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Infrastructure.swift; sourceTree = \"<group>\"; };\n\t\t631751A81D59766500A9DDDC /* PMKA+Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = \"PMKA+Tests.xctest\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t631751AB1D59768200A9DDDC /* 0.0.0.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 0.0.0.swift; sourceTree = \"<group>\"; };\n\t\t631751AC1D59768200A9DDDC /* 2.1.2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 2.1.2.swift; sourceTree = \"<group>\"; };\n\t\t631751AD1D59768200A9DDDC /* 2.1.3.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 2.1.3.swift; sourceTree = \"<group>\"; };\n\t\t631751AE1D59768200A9DDDC /* 2.2.2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 2.2.2.swift; sourceTree = \"<group>\"; };\n\t\t631751AF1D59768200A9DDDC /* 2.2.3.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 2.2.3.swift; sourceTree = \"<group>\"; };\n\t\t631751B01D59768200A9DDDC /* 2.2.4.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 2.2.4.swift; sourceTree = \"<group>\"; };\n\t\t631751B11D59768200A9DDDC /* 2.2.6.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 2.2.6.swift; sourceTree = \"<group>\"; };\n\t\t631751B21D59768200A9DDDC /* 2.2.7.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 2.2.7.swift; sourceTree = \"<group>\"; };\n\t\t631751B31D59768200A9DDDC /* 2.3.1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 2.3.1.swift; sourceTree = \"<group>\"; };\n\t\t631751B41D59768200A9DDDC /* 2.3.2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 2.3.2.swift; sourceTree = \"<group>\"; };\n\t\t631751B51D59768200A9DDDC /* 2.3.4.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 2.3.4.swift; sourceTree = \"<group>\"; };\n\t\t631751B61D59768200A9DDDC /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = \"<group>\"; };\n\t\t632FBBE21F33B273008F8FBB /* Catchable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Catchable.swift; path = Sources/Catchable.swift; sourceTree = \"<group>\"; };\n\t\t632FBBE41F33B338008F8FBB /* CatchableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CatchableTests.swift; sourceTree = \"<group>\"; };\n\t\t633027EA203CC0060037E136 /* PMKDeprecatedTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PMKDeprecatedTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t6330B5E01F2E991200D60528 /* Configuration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Configuration.swift; path = Sources/Configuration.swift; sourceTree = \"<group>\"; };\n\t\t634AAD2A1EAE517C00B17855 /* fwd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fwd.h; path = Sources/fwd.h; sourceTree = \"<group>\"; };\n\t\t635893921D5BE4E000F14B55 /* PromiseKit.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = PromiseKit.playground; sourceTree = \"<group>\"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };\n\t\t635893941D5BE4F900F14B55 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = \"<group>\"; };\n\t\t635893951D5BE4F900F14B55 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = \"<group>\"; };\n\t\t635893971D5BE4F900F14B55 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = \"<group>\"; };\n\t\t635D64081D59635300BC0AF5 /* PromiseTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PromiseTests.swift; sourceTree = \"<group>\"; };\n\t\t635D64091D59635300BC0AF5 /* CancellableErrorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CancellableErrorTests.swift; sourceTree = \"<group>\"; };\n\t\t635D640D1D59635300BC0AF5 /* ZalgoTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZalgoTests.swift; sourceTree = \"<group>\"; };\n\t\t635D640E1D59635300BC0AF5 /* AfterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AfterTests.swift; sourceTree = \"<group>\"; };\n\t\t635D64111D59635300BC0AF5 /* WhenResolvedTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WhenResolvedTests.swift; sourceTree = \"<group>\"; };\n\t\t635D64121D59635300BC0AF5 /* RaceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RaceTests.swift; sourceTree = \"<group>\"; };\n\t\t635D64131D59635300BC0AF5 /* WhenConcurrentTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WhenConcurrentTests.swift; sourceTree = \"<group>\"; };\n\t\t635D64151D59635300BC0AF5 /* WhenTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WhenTests.swift; sourceTree = \"<group>\"; };\n\t\t635D64161D59635300BC0AF5 /* StressTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StressTests.swift; sourceTree = \"<group>\"; };\n\t\t635D64171D59635300BC0AF5 /* RegressionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RegressionTests.swift; sourceTree = \"<group>\"; };\n\t\t635D641B1D59635300BC0AF5 /* DefaultDispatchQueueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultDispatchQueueTests.swift; sourceTree = \"<group>\"; };\n\t\t63648C94203CB97400EBA011 /* DeprecationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DeprecationTests.swift; path = Tests/DeprecationTests.swift; sourceTree = \"<group>\"; };\n\t\t636A29191F1C156B001229C2 /* Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Promise.swift; path = Sources/Promise.swift; sourceTree = \"<group>\"; };\n\t\t636A291E1F1C16FF001229C2 /* Box.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Box.swift; path = Sources/Box.swift; sourceTree = \"<group>\"; };\n\t\t636A29201F1C1716001229C2 /* Thenable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Thenable.swift; path = Sources/Thenable.swift; sourceTree = \"<group>\"; };\n\t\t636A29221F1C17A6001229C2 /* Guarantee.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Guarantee.swift; path = Sources/Guarantee.swift; sourceTree = \"<group>\"; };\n\t\t636A29241F1C3089001229C2 /* race.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = race.swift; path = Sources/race.swift; sourceTree = \"<group>\"; };\n\t\t636A29261F1C3927001229C2 /* Resolver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Resolver.swift; path = Sources/Resolver.swift; sourceTree = \"<group>\"; };\n\t\t639BF755203DF02C00FA577B /* Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utilities.swift; sourceTree = \"<group>\"; };\n\t\t63B0AC571D595E1B00FA21D9 /* PromiseKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PromiseKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t63B0AC611D595E6300FA21D9 /* after.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = after.m; path = Sources/after.m; sourceTree = \"<group>\"; };\n\t\t63B0AC621D595E6300FA21D9 /* after.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = after.swift; path = Sources/after.swift; sourceTree = \"<group>\"; };\n\t\t63B0AC631D595E6300FA21D9 /* AnyPromise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnyPromise.h; path = Sources/AnyPromise.h; sourceTree = \"<group>\"; };\n\t\t63B0AC641D595E6300FA21D9 /* AnyPromise.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AnyPromise.m; path = Sources/AnyPromise.m; sourceTree = \"<group>\"; };\n\t\t63B0AC651D595E6300FA21D9 /* AnyPromise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AnyPromise.swift; path = Sources/AnyPromise.swift; sourceTree = \"<group>\"; };\n\t\t63B0AC661D595E6300FA21D9 /* AnyPromise+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = \"AnyPromise+Private.h\"; path = \"Sources/AnyPromise+Private.h\"; sourceTree = \"<group>\"; };\n\t\t63B0AC671D595E6300FA21D9 /* dispatch_promise.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = dispatch_promise.m; path = Sources/dispatch_promise.m; sourceTree = \"<group>\"; };\n\t\t63B0AC691D595E6300FA21D9 /* Error.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Error.swift; path = Sources/Error.swift; sourceTree = \"<group>\"; };\n\t\t63B0AC6B1D595E6300FA21D9 /* hang.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = hang.m; path = Sources/hang.m; sourceTree = \"<group>\"; };\n\t\t63B0AC6C1D595E6300FA21D9 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Sources/Info.plist; sourceTree = \"<group>\"; };\n\t\t63B0AC6D1D595E6300FA21D9 /* join.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = join.m; path = Sources/join.m; sourceTree = \"<group>\"; };\n\t\t63B0AC6F1D595E6300FA21D9 /* NSMethodSignatureForBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NSMethodSignatureForBlock.m; path = Sources/NSMethodSignatureForBlock.m; sourceTree = \"<group>\"; };\n\t\t63B0AC711D595E6300FA21D9 /* PMKCallVariadicBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PMKCallVariadicBlock.m; path = Sources/PMKCallVariadicBlock.m; sourceTree = \"<group>\"; };\n\t\t63B0AC761D595E6300FA21D9 /* PromiseKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PromiseKit.h; path = Sources/PromiseKit.h; sourceTree = \"<group>\"; };\n\t\t63B0AC7C1D595E6300FA21D9 /* when.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = when.m; path = Sources/when.m; sourceTree = \"<group>\"; };\n\t\t63B0AC7D1D595E6300FA21D9 /* when.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = when.swift; path = Sources/when.swift; sourceTree = \"<group>\"; };\n\t\t63B18AEB1F2D205C00B79E37 /* CustomStringConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CustomStringConvertible.swift; path = Sources/CustomStringConvertible.swift; sourceTree = \"<group>\"; };\n\t\t63B7C94A203E2B8200FBEC00 /* AnyPromiseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyPromiseTests.swift; sourceTree = \"<group>\"; };\n\t\t63B912A91F1D7B1300D49110 /* firstly.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = firstly.swift; path = Sources/firstly.swift; sourceTree = \"<group>\"; };\n\t\t63CF6D79203CC66000EC8927 /* ErrorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorTests.swift; sourceTree = \"<group>\"; };\n\t\t63CF6D7B203CCDAB00EC8927 /* GuaranteeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GuaranteeTests.swift; sourceTree = \"<group>\"; };\n\t\t63CF6D7F203CD19200EC8927 /* ThenableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThenableTests.swift; sourceTree = \"<group>\"; };\n\t\t63D9B2EE203385FD0075C00B /* race.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = race.m; path = Sources/race.m; sourceTree = \"<group>\"; };\n\t\t63D9B2F020338D5D0075C00B /* Deprecations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Deprecations.swift; path = Sources/Deprecations.swift; sourceTree = \"<group>\"; };\n\t\t9E4170F8287D88C800A3B4B5 /* Async.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Async.swift; path = Sources/Async.swift; sourceTree = \"<group>\"; };\n\t\t9E4170FA287D8DBD00A3B4B5 /* AsyncTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncTests.swift; sourceTree = \"<group>\"; };\n\t\t9E66231526FE5A8C00FA25CB /* RaceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RaceTests.m; sourceTree = \"<group>\"; };\n\t\t9E8028F72BDCEDBC0081E2D1 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = \"<group>\"; };\n\t\t9EC774262991495C00803027 /* Combine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Combine.swift; path = Sources/Combine.swift; sourceTree = \"<group>\"; };\n\t\t9EC774282991497900803027 /* CombineTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CombineTests.swift; sourceTree = \"<group>\"; };\n\t\tC013F7372048E3B6006B57B1 /* MockNodeEnvironment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MockNodeEnvironment.swift; path = \"Tests/JS-A+/MockNodeEnvironment.swift\"; sourceTree = \"<group>\"; };\n\t\tC013F7392049076A006B57B1 /* JSPromise.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = JSPromise.swift; path = \"Tests/JS-A+/JSPromise.swift\"; sourceTree = \"<group>\"; };\n\t\tC013F73B20494291006B57B1 /* JSAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = JSAdapter.swift; path = \"Tests/JS-A+/JSAdapter.swift\"; sourceTree = \"<group>\"; };\n\t\tC013F73F204E5063006B57B1 /* JSUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSUtils.swift; path = \"Tests/JS-A+/JSUtils.swift\"; sourceTree = \"<group>\"; };\n\t\tC0244E622047A6CB00ACB4AC /* PMKJSA+Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = \"PMKJSA+Tests.xctest\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tC0244E682047AC9F00ACB4AC /* AllTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AllTests.swift; path = \"Tests/JS-A+/AllTests.swift\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t630019181D596292003B4E30 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t635D64301D596E8500BC0AF5 /* PromiseKit.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t631411371D59795700E24B9E /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t631411381D59795700E24B9E /* PromiseKit.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t631751A31D59766500A9DDDC /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t631751A41D59766500A9DDDC /* PromiseKit.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t633027E5203CC0060037E136 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t633027E6203CC0060037E136 /* PromiseKit.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t63B0AC531D595E1B00FA21D9 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC0244E5D2047A6CB00ACB4AC /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC0244E5E2047A6CB00ACB4AC /* PromiseKit.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t630A8050203CEF6800D25F23 /* CoreObjC */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t630A8051203CEF6800D25F23 /* AnyPromiseTests.m */,\n\t\t\t\t63B7C94A203E2B8200FBEC00 /* AnyPromiseTests.swift */,\n\t\t\t\t630A8052203CEF6800D25F23 /* PMKManifoldTests.m */,\n\t\t\t\t630A8053203CEF6800D25F23 /* JoinTests.m */,\n\t\t\t\t630A8054203CEF6800D25F23 /* HangTests.m */,\n\t\t\t\t630A8055203CEF6800D25F23 /* WhenTests.m */,\n\t\t\t\t9E66231526FE5A8C00FA25CB /* RaceTests.m */,\n\t\t\t);\n\t\t\tname = CoreObjC;\n\t\t\tpath = Tests/CoreObjC;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t630B60BF1F2F739E00A1AEFE /* Features */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t63B0AC611D595E6300FA21D9 /* after.m */,\n\t\t\t\t63B0AC6B1D595E6300FA21D9 /* hang.m */,\n\t\t\t\t63B0AC6D1D595E6300FA21D9 /* join.m */,\n\t\t\t\t63B0AC7C1D595E6300FA21D9 /* when.m */,\n\t\t\t\t63D9B2EE203385FD0075C00B /* race.m */,\n\t\t\t);\n\t\t\tname = Features;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t630B60C01F2F73B000A1AEFE /* Headers */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t634AAD2A1EAE517C00B17855 /* fwd.h */,\n\t\t\t\t63B0AC631D595E6300FA21D9 /* AnyPromise.h */,\n\t\t\t);\n\t\t\tname = Headers;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6314113D1D59797100E24B9E /* Bridging */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6314113E1D59797100E24B9E /* BridgingTests.m */,\n\t\t\t\t6314113F1D59797100E24B9E /* BridgingTests.swift */,\n\t\t\t\t631411401D59797100E24B9E /* Infrastructure.h */,\n\t\t\t\t631411411D59797100E24B9E /* Infrastructure.m */,\n\t\t\t\t631411421D59797100E24B9E /* Infrastructure.swift */,\n\t\t\t);\n\t\t\tname = Bridging;\n\t\t\tpath = Tests/Bridging;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6317518A1D59765700A9DDDC /* Core */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9E4170FA287D8DBD00A3B4B5 /* AsyncTests.swift */,\n\t\t\t\t9EC774282991497900803027 /* CombineTests.swift */,\n\t\t\t\t63CF6D7F203CD19200EC8927 /* ThenableTests.swift */,\n\t\t\t\t632FBBE41F33B338008F8FBB /* CatchableTests.swift */,\n\t\t\t\t635D64081D59635300BC0AF5 /* PromiseTests.swift */,\n\t\t\t\t49A5584B1DC5172F00E4D01B /* ResolverTests.swift */,\n\t\t\t\t63CF6D7B203CCDAB00EC8927 /* GuaranteeTests.swift */,\n\t\t\t\t635D64091D59635300BC0AF5 /* CancellableErrorTests.swift */,\n\t\t\t\t63CF6D79203CC66000EC8927 /* ErrorTests.swift */,\n\t\t\t\t635D64151D59635300BC0AF5 /* WhenTests.swift */,\n\t\t\t\t635D64131D59635300BC0AF5 /* WhenConcurrentTests.swift */,\n\t\t\t\t635D64111D59635300BC0AF5 /* WhenResolvedTests.swift */,\n\t\t\t\t635D640E1D59635300BC0AF5 /* AfterTests.swift */,\n\t\t\t\t0C42F3191FCF86240051309C /* HangTests.swift */,\n\t\t\t\t635D64121D59635300BC0AF5 /* RaceTests.swift */,\n\t\t\t\t635D641B1D59635300BC0AF5 /* DefaultDispatchQueueTests.swift */,\n\t\t\t\t635D64171D59635300BC0AF5 /* RegressionTests.swift */,\n\t\t\t\t635D64161D59635300BC0AF5 /* StressTests.swift */,\n\t\t\t\t635D640D1D59635300BC0AF5 /* ZalgoTests.swift */,\n\t\t\t\t639BF755203DF02C00FA577B /* Utilities.swift */,\n\t\t\t\t085B96B121A6358900E5E22F /* LoggingTests.swift */,\n\t\t\t);\n\t\t\tname = Core;\n\t\t\tpath = Tests/CorePromise;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t631751AA1D59768200A9DDDC /* A+ */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t631751AB1D59768200A9DDDC /* 0.0.0.swift */,\n\t\t\t\t631751AC1D59768200A9DDDC /* 2.1.2.swift */,\n\t\t\t\t631751AD1D59768200A9DDDC /* 2.1.3.swift */,\n\t\t\t\t631751AE1D59768200A9DDDC /* 2.2.2.swift */,\n\t\t\t\t631751AF1D59768200A9DDDC /* 2.2.3.swift */,\n\t\t\t\t631751B01D59768200A9DDDC /* 2.2.4.swift */,\n\t\t\t\t631751B11D59768200A9DDDC /* 2.2.6.swift */,\n\t\t\t\t631751B21D59768200A9DDDC /* 2.2.7.swift */,\n\t\t\t\t631751B31D59768200A9DDDC /* 2.3.1.swift */,\n\t\t\t\t631751B41D59768200A9DDDC /* 2.3.2.swift */,\n\t\t\t\t631751B51D59768200A9DDDC /* 2.3.4.swift */,\n\t\t\t\t631751B61D59768200A9DDDC /* README.md */,\n\t\t\t);\n\t\t\tname = \"A+\";\n\t\t\tpath = \"Tests/A+\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t635893991D5BE51700F14B55 /* … */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t63B0AC581D595E1B00FA21D9 /* Products */,\n\t\t\t\t63B0AC6C1D595E6300FA21D9 /* Info.plist */,\n\t\t\t\t635893941D5BE4F900F14B55 /* LICENSE */,\n\t\t\t\t635893951D5BE4F900F14B55 /* Package.swift */,\n\t\t\t\t1F1DCDF72A27AB6400E7A16B /* PromiseKit.podspec */,\n\t\t\t);\n\t\t\tname = \"…\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t635D64061D59630200BC0AF5 /* Tests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC0244E6B2047ACAF00ACB4AC /* JS/A+ */,\n\t\t\t\t631751AA1D59768200A9DDDC /* A+ */,\n\t\t\t\t6314113D1D59797100E24B9E /* Bridging */,\n\t\t\t\t6317518A1D59765700A9DDDC /* Core */,\n\t\t\t\t630A8050203CEF6800D25F23 /* CoreObjC */,\n\t\t\t\t63648C94203CB97400EBA011 /* DeprecationTests.swift */,\n\t\t\t);\n\t\t\tname = Tests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6399A3711D595D9100D65233 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t635893971D5BE4F900F14B55 /* README.md */,\n\t\t\t\t635893921D5BE4E000F14B55 /* PromiseKit.playground */,\n\t\t\t\t63B0AC761D595E6300FA21D9 /* PromiseKit.h */,\n\t\t\t\t63B0AC601D595E4C00FA21D9 /* Sources.swift */,\n\t\t\t\t63B912AB1F1E657400D49110 /* Sources.objc */,\n\t\t\t\t635D64061D59630200BC0AF5 /* Tests */,\n\t\t\t\t635893991D5BE51700F14B55 /* … */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t63B0AC581D595E1B00FA21D9 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t63B0AC571D595E1B00FA21D9 /* PromiseKit.framework */,\n\t\t\t\t630019221D596292003B4E30 /* PMKCoreTests.xctest */,\n\t\t\t\t631751A81D59766500A9DDDC /* PMKA+Tests.xctest */,\n\t\t\t\t6314113C1D59795700E24B9E /* PMKBridgeTests.xctest */,\n\t\t\t\t633027EA203CC0060037E136 /* PMKDeprecatedTests.xctest */,\n\t\t\t\tC0244E622047A6CB00ACB4AC /* PMKJSA+Tests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t63B0AC601D595E4C00FA21D9 /* Sources.swift */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9E4170F8287D88C800A3B4B5 /* Async.swift */,\n\t\t\t\t9EC774262991495C00803027 /* Combine.swift */,\n\t\t\t\t636A29191F1C156B001229C2 /* Promise.swift */,\n\t\t\t\t636A29221F1C17A6001229C2 /* Guarantee.swift */,\n\t\t\t\t636A29201F1C1716001229C2 /* Thenable.swift */,\n\t\t\t\t632FBBE21F33B273008F8FBB /* Catchable.swift */,\n\t\t\t\t63B912AC1F1E663E00D49110 /* Features */,\n\t\t\t\t63B0AC691D595E6300FA21D9 /* Error.swift */,\n\t\t\t\t636A29261F1C3927001229C2 /* Resolver.swift */,\n\t\t\t\t636A291E1F1C16FF001229C2 /* Box.swift */,\n\t\t\t\t6330B5E01F2E991200D60528 /* Configuration.swift */,\n\t\t\t\t63B18AEB1F2D205C00B79E37 /* CustomStringConvertible.swift */,\n\t\t\t\t63D9B2F020338D5D0075C00B /* Deprecations.swift */,\n\t\t\t\t085B96BE21A9B37C00E5E22F /* LogEvent.swift */,\n\t\t\t\t9E8028F82BDCEDBC0081E2D1 /* Resources */,\n\t\t\t);\n\t\t\tname = Sources.swift;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t63B0AC9D1D595E6E00FA21D9 /* Internal Utilities */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t63B0AC661D595E6300FA21D9 /* AnyPromise+Private.h */,\n\t\t\t\t63B0AC6F1D595E6300FA21D9 /* NSMethodSignatureForBlock.m */,\n\t\t\t\t63B0AC711D595E6300FA21D9 /* PMKCallVariadicBlock.m */,\n\t\t\t);\n\t\t\tname = \"Internal Utilities\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t63B912AB1F1E657400D49110 /* Sources.objc */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t63B0AC641D595E6300FA21D9 /* AnyPromise.m */,\n\t\t\t\t63B0AC651D595E6300FA21D9 /* AnyPromise.swift */,\n\t\t\t\t63B0AC671D595E6300FA21D9 /* dispatch_promise.m */,\n\t\t\t\t630B60C01F2F73B000A1AEFE /* Headers */,\n\t\t\t\t630B60BF1F2F739E00A1AEFE /* Features */,\n\t\t\t\t63B0AC9D1D595E6E00FA21D9 /* Internal Utilities */,\n\t\t\t);\n\t\t\tname = Sources.objc;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t63B912AC1F1E663E00D49110 /* Features */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t0CC3AF2A1FCF84F7000E98C9 /* hang.swift */,\n\t\t\t\t63B0AC621D595E6300FA21D9 /* after.swift */,\n\t\t\t\t63B912A91F1D7B1300D49110 /* firstly.swift */,\n\t\t\t\t636A29241F1C3089001229C2 /* race.swift */,\n\t\t\t\t63B0AC7D1D595E6300FA21D9 /* when.swift */,\n\t\t\t);\n\t\t\tname = Features;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9E8028F82BDCEDBC0081E2D1 /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9E8028F72BDCEDBC0081E2D1 /* PrivacyInfo.xcprivacy */,\n\t\t\t);\n\t\t\tname = Resources;\n\t\t\tpath = Sources/Resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC0244E6B2047ACAF00ACB4AC /* JS/A+ */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC0244E682047AC9F00ACB4AC /* AllTests.swift */,\n\t\t\t\tC013F7372048E3B6006B57B1 /* MockNodeEnvironment.swift */,\n\t\t\t\tC013F7392049076A006B57B1 /* JSPromise.swift */,\n\t\t\t\tC013F73B20494291006B57B1 /* JSAdapter.swift */,\n\t\t\t\tC013F73F204E5063006B57B1 /* JSUtils.swift */,\n\t\t\t);\n\t\t\tname = \"JS/A+\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXHeadersBuildPhase section */\n\t\t63B0AC541D595E1B00FA21D9 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t63B0AC931D595E6300FA21D9 /* PromiseKit.h in Headers */,\n\t\t\t\t634AAD2B1EAE517C00B17855 /* fwd.h in Headers */,\n\t\t\t\t63B0AC811D595E6300FA21D9 /* AnyPromise.h in Headers */,\n\t\t\t\t63B0AC841D595E6300FA21D9 /* AnyPromise+Private.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXHeadersBuildPhase section */\n\n/* Begin PBXNativeTarget section */\n\t\t630019011D596292003B4E30 /* PMKCoreTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 6300191F1D596292003B4E30 /* Build configuration list for PBXNativeTarget \"PMKCoreTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t630019021D596292003B4E30 /* Sources */,\n\t\t\t\t630019181D596292003B4E30 /* Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t635D64051D5962F900BC0AF5 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = PMKCoreTests;\n\t\t\tproductName = PromiseKit;\n\t\t\tproductReference = 630019221D596292003B4E30 /* PMKCoreTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t631411321D59795700E24B9E /* PMKBridgeTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 631411391D59795700E24B9E /* Build configuration list for PBXNativeTarget \"PMKBridgeTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t631411351D59795700E24B9E /* Sources */,\n\t\t\t\t631411371D59795700E24B9E /* Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t631411331D59795700E24B9E /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = PMKBridgeTests;\n\t\t\tproductName = PromiseKit;\n\t\t\tproductReference = 6314113C1D59795700E24B9E /* PMKBridgeTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t6317518B1D59766500A9DDDC /* PMKA+Tests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 631751A51D59766500A9DDDC /* Build configuration list for PBXNativeTarget \"PMKA+Tests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t6317518E1D59766500A9DDDC /* Sources */,\n\t\t\t\t631751A31D59766500A9DDDC /* Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t6317518C1D59766500A9DDDC /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = \"PMKA+Tests\";\n\t\t\tproductName = PromiseKit;\n\t\t\tproductReference = 631751A81D59766500A9DDDC /* PMKA+Tests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t633027E0203CC0060037E136 /* PMKDeprecatedTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 633027E7203CC0060037E136 /* Build configuration list for PBXNativeTarget \"PMKDeprecatedTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t633027E3203CC0060037E136 /* Sources */,\n\t\t\t\t633027E5203CC0060037E136 /* Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t633027E1203CC0060037E136 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = PMKDeprecatedTests;\n\t\t\tproductName = PromiseKit;\n\t\t\tproductReference = 633027EA203CC0060037E136 /* PMKDeprecatedTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t63B0AC561D595E1B00FA21D9 /* PromiseKit */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 63B0AC5F1D595E1B00FA21D9 /* Build configuration list for PBXNativeTarget \"PromiseKit\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t63B0AC541D595E1B00FA21D9 /* Headers */,\n\t\t\t\t63B0AC521D595E1B00FA21D9 /* Sources */,\n\t\t\t\t63B0AC531D595E1B00FA21D9 /* Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = PromiseKit;\n\t\t\tproductName = PromiseKit;\n\t\t\tproductReference = 63B0AC571D595E1B00FA21D9 /* PromiseKit.framework */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\tC0244E4E2047A6CB00ACB4AC /* PMKJSA+Tests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = C0244E5F2047A6CB00ACB4AC /* Build configuration list for PBXNativeTarget \"PMKJSA+Tests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tC0244E512047A6CB00ACB4AC /* Sources */,\n\t\t\t\tC0244E5D2047A6CB00ACB4AC /* Frameworks */,\n\t\t\t\tC0244E6E2047AF0B00ACB4AC /* CopyFiles */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tC0244E4F2047A6CB00ACB4AC /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = \"PMKJSA+Tests\";\n\t\t\tproductName = PromiseKit;\n\t\t\tproductReference = C0244E622047A6CB00ACB4AC /* PMKJSA+Tests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t6399A3721D595D9100D65233 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 1250;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t630019011D596292003B4E30 = {\n\t\t\t\t\t\tLastSwiftMigration = 1100;\n\t\t\t\t\t};\n\t\t\t\t\t631411321D59795700E24B9E = {\n\t\t\t\t\t\tLastSwiftMigration = 1100;\n\t\t\t\t\t};\n\t\t\t\t\t6317518B1D59766500A9DDDC = {\n\t\t\t\t\t\tLastSwiftMigration = 1100;\n\t\t\t\t\t};\n\t\t\t\t\t633027E0203CC0060037E136 = {\n\t\t\t\t\t\tLastSwiftMigration = 1100;\n\t\t\t\t\t};\n\t\t\t\t\t63B0AC561D595E1B00FA21D9 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.0;\n\t\t\t\t\t\tLastSwiftMigration = 1100;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t};\n\t\t\t\t\tC0244E4E2047A6CB00ACB4AC = {\n\t\t\t\t\t\tLastSwiftMigration = 1100;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 6399A3751D595D9100D65233 /* Build configuration list for PBXProject \"PromiseKit\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 6399A3711D595D9100D65233;\n\t\t\tproductRefGroup = 63B0AC581D595E1B00FA21D9 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t63B0AC561D595E1B00FA21D9 /* PromiseKit */,\n\t\t\t\t6317518B1D59766500A9DDDC /* PMKA+Tests */,\n\t\t\t\t631411321D59795700E24B9E /* PMKBridgeTests */,\n\t\t\t\t630019011D596292003B4E30 /* PMKCoreTests */,\n\t\t\t\t633027E0203CC0060037E136 /* PMKDeprecatedTests */,\n\t\t\t\tC0244E4E2047A6CB00ACB4AC /* PMKJSA+Tests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t630019021D596292003B4E30 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t0C42F31B1FCF86320051309C /* HangTests.swift in Sources */,\n\t\t\t\t635D641E1D59635300BC0AF5 /* CancellableErrorTests.swift in Sources */,\n\t\t\t\t630A8056203CEF6800D25F23 /* AnyPromiseTests.m in Sources */,\n\t\t\t\t635D64221D59635300BC0AF5 /* ZalgoTests.swift in Sources */,\n\t\t\t\t635D64271D59635300BC0AF5 /* RaceTests.swift in Sources */,\n\t\t\t\t9EC7742A2991498200803027 /* CombineTests.swift in Sources */,\n\t\t\t\t632FBBE51F33B338008F8FBB /* CatchableTests.swift in Sources */,\n\t\t\t\t63CF6D80203CD19200EC8927 /* ThenableTests.swift in Sources */,\n\t\t\t\t635D642B1D59635300BC0AF5 /* StressTests.swift in Sources */,\n\t\t\t\t630A805A203CEF6800D25F23 /* WhenTests.m in Sources */,\n\t\t\t\t630A805B203CF67800D25F23 /* DefaultDispatchQueueTests.swift in Sources */,\n\t\t\t\t635D641D1D59635300BC0AF5 /* PromiseTests.swift in Sources */,\n\t\t\t\t63CF6D7C203CCDAB00EC8927 /* GuaranteeTests.swift in Sources */,\n\t\t\t\t9E66231626FE5A8C00FA25CB /* RaceTests.m in Sources */,\n\t\t\t\t639BF757203DF03100FA577B /* Utilities.swift in Sources */,\n\t\t\t\t9E4170FC287D8DF900A3B4B5 /* AsyncTests.swift in Sources */,\n\t\t\t\t635D64261D59635300BC0AF5 /* WhenResolvedTests.swift in Sources */,\n\t\t\t\t635D64231D59635300BC0AF5 /* AfterTests.swift in Sources */,\n\t\t\t\t63CF6D7A203CC66000EC8927 /* ErrorTests.swift in Sources */,\n\t\t\t\t49A5584D1DC5185900E4D01B /* ResolverTests.swift in Sources */,\n\t\t\t\t630A8057203CEF6800D25F23 /* PMKManifoldTests.m in Sources */,\n\t\t\t\t085B96B321A6359500E5E22F /* LoggingTests.swift in Sources */,\n\t\t\t\t63B7C94B203E2B8200FBEC00 /* AnyPromiseTests.swift in Sources */,\n\t\t\t\t630A8059203CEF6800D25F23 /* HangTests.m in Sources */,\n\t\t\t\t635D642A1D59635300BC0AF5 /* WhenTests.swift in Sources */,\n\t\t\t\t630A8058203CEF6800D25F23 /* JoinTests.m in Sources */,\n\t\t\t\t635D64281D59635300BC0AF5 /* WhenConcurrentTests.swift in Sources */,\n\t\t\t\t635D642C1D59635300BC0AF5 /* RegressionTests.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t631411351D59795700E24B9E /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t631411461D59797100E24B9E /* Infrastructure.swift in Sources */,\n\t\t\t\t631411431D59797100E24B9E /* BridgingTests.m in Sources */,\n\t\t\t\t631411441D59797100E24B9E /* BridgingTests.swift in Sources */,\n\t\t\t\t631411451D59797100E24B9E /* Infrastructure.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6317518E1D59766500A9DDDC /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t631751C11D59768200A9DDDC /* 2.3.4.swift in Sources */,\n\t\t\t\t631751BA1D59768200A9DDDC /* 2.2.2.swift in Sources */,\n\t\t\t\t631751BF1D59768200A9DDDC /* 2.3.1.swift in Sources */,\n\t\t\t\t631751B91D59768200A9DDDC /* 2.1.3.swift in Sources */,\n\t\t\t\t631751BD1D59768200A9DDDC /* 2.2.6.swift in Sources */,\n\t\t\t\t631751B71D59768200A9DDDC /* 0.0.0.swift in Sources */,\n\t\t\t\t631751C01D59768200A9DDDC /* 2.3.2.swift in Sources */,\n\t\t\t\t631751B81D59768200A9DDDC /* 2.1.2.swift in Sources */,\n\t\t\t\t631751BE1D59768200A9DDDC /* 2.2.7.swift in Sources */,\n\t\t\t\t631751BC1D59768200A9DDDC /* 2.2.4.swift in Sources */,\n\t\t\t\t631751BB1D59768200A9DDDC /* 2.2.3.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t633027E3203CC0060037E136 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t63CF6D7E203CD12700EC8927 /* DeprecationTests.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t63B0AC521D595E1B00FA21D9 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t636A29251F1C3089001229C2 /* race.swift in Sources */,\n\t\t\t\t63B0AC9A1D595E6300FA21D9 /* when.swift in Sources */,\n\t\t\t\t636A29271F1C3927001229C2 /* Resolver.swift in Sources */,\n\t\t\t\t63B0AC991D595E6300FA21D9 /* when.m in Sources */,\n\t\t\t\t63D9B2EF203385FD0075C00B /* race.m in Sources */,\n\t\t\t\t63B0AC801D595E6300FA21D9 /* after.swift in Sources */,\n\t\t\t\t63B18AEC1F2D205C00B79E37 /* CustomStringConvertible.swift in Sources */,\n\t\t\t\t085B96BF21A9B37C00E5E22F /* LogEvent.swift in Sources */,\n\t\t\t\t9E4170F9287D88C900A3B4B5 /* Async.swift in Sources */,\n\t\t\t\t6330B5E11F2E991200D60528 /* Configuration.swift in Sources */,\n\t\t\t\t63B912AA1F1D7B1300D49110 /* firstly.swift in Sources */,\n\t\t\t\t636A29211F1C1716001229C2 /* Thenable.swift in Sources */,\n\t\t\t\t632FBBE31F33B273008F8FBB /* Catchable.swift in Sources */,\n\t\t\t\t63B0AC851D595E6300FA21D9 /* dispatch_promise.m in Sources */,\n\t\t\t\t636A291F1F1C16FF001229C2 /* Box.swift in Sources */,\n\t\t\t\t63B0AC821D595E6300FA21D9 /* AnyPromise.m in Sources */,\n\t\t\t\t636A29231F1C17A6001229C2 /* Guarantee.swift in Sources */,\n\t\t\t\t636A291A1F1C156B001229C2 /* Promise.swift in Sources */,\n\t\t\t\t63B0AC8B1D595E6300FA21D9 /* join.m in Sources */,\n\t\t\t\t63B0AC891D595E6300FA21D9 /* hang.m in Sources */,\n\t\t\t\t63B0AC831D595E6300FA21D9 /* AnyPromise.swift in Sources */,\n\t\t\t\t9EC774272991495C00803027 /* Combine.swift in Sources */,\n\t\t\t\t63D9B2F120338D5D0075C00B /* Deprecations.swift in Sources */,\n\t\t\t\t63B0AC871D595E6300FA21D9 /* Error.swift in Sources */,\n\t\t\t\t0CC3AF2B1FCF84F7000E98C9 /* hang.swift in Sources */,\n\t\t\t\t63B0AC7F1D595E6300FA21D9 /* after.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC0244E512047A6CB00ACB4AC /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC013F73C20494291006B57B1 /* JSAdapter.swift in Sources */,\n\t\t\t\tC0244E692047AC9F00ACB4AC /* AllTests.swift in Sources */,\n\t\t\t\tC013F740204E5064006B57B1 /* JSUtils.swift in Sources */,\n\t\t\t\tC013F73A2049076A006B57B1 /* JSPromise.swift in Sources */,\n\t\t\t\tC013F7382048E3B6006B57B1 /* MockNodeEnvironment.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\t631411331D59795700E24B9E /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 63B0AC561D595E1B00FA21D9 /* PromiseKit */;\n\t\t\ttargetProxy = 631411341D59795700E24B9E /* PBXContainerItemProxy */;\n\t\t};\n\t\t6317518C1D59766500A9DDDC /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 63B0AC561D595E1B00FA21D9 /* PromiseKit */;\n\t\t\ttargetProxy = 6317518D1D59766500A9DDDC /* PBXContainerItemProxy */;\n\t\t};\n\t\t633027E1203CC0060037E136 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 63B0AC561D595E1B00FA21D9 /* PromiseKit */;\n\t\t\ttargetProxy = 633027E2203CC0060037E136 /* PBXContainerItemProxy */;\n\t\t};\n\t\t635D64051D5962F900BC0AF5 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 63B0AC561D595E1B00FA21D9 /* PromiseKit */;\n\t\t\ttargetProxy = 635D64041D5962F900BC0AF5 /* PBXContainerItemProxy */;\n\t\t};\n\t\tC0244E4F2047A6CB00ACB4AC /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 63B0AC561D595E1B00FA21D9 /* PromiseKit */;\n\t\t\ttargetProxy = C0244E502047A6CB00ACB4AC /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin XCBuildConfiguration section */\n\t\t630019201D596292003B4E30 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\t\"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]\" = \"$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks\";\n\t\t\t\tSWIFT_INSTALL_OBJC_HEADER = NO;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t630019211D596292003B4E30 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\t\"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]\" = \"$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks\";\n\t\t\t\tSWIFT_INSTALL_OBJC_HEADER = NO;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6314113A1D59795700E24B9E /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\t\"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]\" = \"$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks\";\n\t\t\t\tSWIFT_INSTALL_OBJC_HEADER = NO;\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = Tests/Bridging/Infrastructure.h;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6314113B1D59795700E24B9E /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\t\"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]\" = \"$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks\";\n\t\t\t\tSWIFT_INSTALL_OBJC_HEADER = NO;\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = Tests/Bridging/Infrastructure.h;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t631751A61D59766500A9DDDC /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\t\"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]\" = \"$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks\";\n\t\t\t\tSWIFT_INSTALL_OBJC_HEADER = NO;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t631751A71D59766500A9DDDC /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"@executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\t\"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]\" = \"$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks\";\n\t\t\t\tSWIFT_INSTALL_OBJC_HEADER = NO;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t633027E8203CC0060037E136 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\t\"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]\" = \"$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_INSTALL_OBJC_HEADER = NO;\n\t\t\t\tSWIFT_SUPPRESS_WARNINGS = YES;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t633027E9203CC0060037E136 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\t\"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]\" = \"$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_INSTALL_OBJC_HEADER = NO;\n\t\t\t\tSWIFT_SUPPRESS_WARNINGS = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6399A3761D595D9100D65233 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tCURRENT_PROJECT_VERSION = 8.2.0;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = \"DEBUG=1\";\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Sources/Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 11.0;\n\t\t\t\tLD_DYLIB_INSTALL_NAME = \"@rpath\";\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.13;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = org.promisekit;\n\t\t\t\tPRODUCT_BUNDLE_PACKAGE_TYPE = BNDL;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSUPPORTED_PLATFORMS = \"macosx appletvsimulator appletvos watchsimulator iphonesimulator watchos iphoneos\";\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 11.0;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tWATCHOS_DEPLOYMENT_TARGET = 4.0;\n\t\t\t\tXROS_DEPLOYMENT_TARGET = 1.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6399A3771D595D9100D65233 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tCURRENT_PROJECT_VERSION = 8.2.0;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Sources/Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 11.0;\n\t\t\t\tLD_DYLIB_INSTALL_NAME = \"@rpath\";\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.13;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = org.promisekit;\n\t\t\t\tPRODUCT_BUNDLE_PACKAGE_TYPE = BNDL;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSUPPORTED_PLATFORMS = \"macosx appletvsimulator appletvos watchsimulator iphonesimulator watchos iphoneos\";\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Owholemodule\";\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 11.0;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tWATCHOS_DEPLOYMENT_TARGET = 4.0;\n\t\t\t\tXROS_DEPLOYMENT_TARGET = 1.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t63B0AC5D1D595E1B00FA21D9 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tAPPLICATION_EXTENSION_API_ONLY = YES;\n\t\t\t\tCLANG_WARN_ASSIGN_ENUM = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CXX0X_EXTENSIONS = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES;\n\t\t\t\tCLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN__EXIT_TIME_DESTRUCTORS = YES;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;\n\t\t\t\tGCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;\n\t\t\t\tGCC_TREAT_WARNINGS_AS_ERRORS = NO;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_NEWLINE = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;\n\t\t\t\tGCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;\n\t\t\t\tGCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;\n\t\t\t\tGCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;\n\t\t\t\tGCC_WARN_SIGN_COMPARE = YES;\n\t\t\t\tGCC_WARN_STRICT_SELECTOR_MATCH = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNKNOWN_PRAGMAS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_LABEL = YES;\n\t\t\t\tGCC_WARN_UNUSED_PARAMETER = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tLD_DYLIB_INSTALL_NAME = \"$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_PACKAGE_TYPE = FMWK;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSUPPORTED_PLATFORMS = \"$(AVAILABLE_PLATFORMS)\";\n\t\t\t\tSUPPORTS_MACCATALYST = YES;\n\t\t\t\tSUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;\n\t\t\t\tSWIFT_TREAT_WARNINGS_AS_ERRORS = NO;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2,3,4,6,7\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t63B0AC5E1D595E1B00FA21D9 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tAPPLICATION_EXTENSION_API_ONLY = YES;\n\t\t\t\tBITCODE_GENERATION_MODE = bitcode;\n\t\t\t\tCLANG_WARN_ASSIGN_ENUM = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CXX0X_EXTENSIONS = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES;\n\t\t\t\tCLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN__EXIT_TIME_DESTRUCTORS = YES;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tGCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;\n\t\t\t\tGCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;\n\t\t\t\tGCC_TREAT_WARNINGS_AS_ERRORS = NO;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_NEWLINE = YES;\n\t\t\t\tGCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;\n\t\t\t\tGCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;\n\t\t\t\tGCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;\n\t\t\t\tGCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;\n\t\t\t\tGCC_WARN_SIGN_COMPARE = YES;\n\t\t\t\tGCC_WARN_STRICT_SELECTOR_MATCH = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNKNOWN_PRAGMAS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_LABEL = YES;\n\t\t\t\tGCC_WARN_UNUSED_PARAMETER = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tLD_DYLIB_INSTALL_NAME = \"$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_PACKAGE_TYPE = FMWK;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSUPPORTED_PLATFORMS = \"$(AVAILABLE_PLATFORMS)\";\n\t\t\t\tSUPPORTS_MACCATALYST = YES;\n\t\t\t\tSUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;\n\t\t\t\tSWIFT_TREAT_WARNINGS_AS_ERRORS = NO;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2,3,4,6,7\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tC0244E602047A6CB00ACB4AC /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\t\"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]\" = \"$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_INSTALL_OBJC_HEADER = NO;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tC0244E612047A6CB00ACB4AC /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"@executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\t\"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]\" = \"$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_INSTALL_OBJC_HEADER = NO;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t6300191F1D596292003B4E30 /* Build configuration list for PBXNativeTarget \"PMKCoreTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t630019201D596292003B4E30 /* Debug */,\n\t\t\t\t630019211D596292003B4E30 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t631411391D59795700E24B9E /* Build configuration list for PBXNativeTarget \"PMKBridgeTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6314113A1D59795700E24B9E /* Debug */,\n\t\t\t\t6314113B1D59795700E24B9E /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t631751A51D59766500A9DDDC /* Build configuration list for PBXNativeTarget \"PMKA+Tests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t631751A61D59766500A9DDDC /* Debug */,\n\t\t\t\t631751A71D59766500A9DDDC /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t633027E7203CC0060037E136 /* Build configuration list for PBXNativeTarget \"PMKDeprecatedTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t633027E8203CC0060037E136 /* Debug */,\n\t\t\t\t633027E9203CC0060037E136 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t6399A3751D595D9100D65233 /* Build configuration list for PBXProject \"PromiseKit\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6399A3761D595D9100D65233 /* Debug */,\n\t\t\t\t6399A3771D595D9100D65233 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t63B0AC5F1D595E1B00FA21D9 /* Build configuration list for PBXNativeTarget \"PromiseKit\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t63B0AC5D1D595E1B00FA21D9 /* Debug */,\n\t\t\t\t63B0AC5E1D595E1B00FA21D9 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tC0244E5F2047A6CB00ACB4AC /* Build configuration list for PBXNativeTarget \"PMKJSA+Tests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tC0244E602047A6CB00ACB4AC /* Debug */,\n\t\t\t\tC0244E612047A6CB00ACB4AC /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 6399A3721D595D9100D65233 /* Project object */;\n}\n"
  },
  {
    "path": "PromiseKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "PromiseKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "PromiseKit.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>\n\t<false/>\n</dict>\n</plist>\n"
  },
  {
    "path": "PromiseKit.xcodeproj/xcshareddata/xcschemes/PromiseKit.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1250\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"NO\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"NO\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"63B0AC561D595E1B00FA21D9\"\n               BuildableName = \"PromiseKit.framework\"\n               BlueprintName = \"PromiseKit\"\n               ReferencedContainer = \"container:PromiseKit.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      codeCoverageEnabled = \"YES\"\n      onlyGenerateCoverageForSpecifiedTargets = \"YES\">\n      <CodeCoverageTargets>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"63B0AC561D595E1B00FA21D9\"\n            BuildableName = \"PromiseKit.framework\"\n            BlueprintName = \"PromiseKit\"\n            ReferencedContainer = \"container:PromiseKit.xcodeproj\">\n         </BuildableReference>\n      </CodeCoverageTargets>\n      <Testables>\n         <TestableReference\n            skipped = \"NO\"\n            parallelizable = \"YES\"\n            testExecutionOrdering = \"random\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"630019011D596292003B4E30\"\n               BuildableName = \"PMKCoreTests.xctest\"\n               BlueprintName = \"PMKCoreTests\"\n               ReferencedContainer = \"container:PromiseKit.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n         <TestableReference\n            skipped = \"NO\"\n            parallelizable = \"YES\"\n            testExecutionOrdering = \"random\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"6317518B1D59766500A9DDDC\"\n               BuildableName = \"PMKA+Tests.xctest\"\n               BlueprintName = \"PMKA+Tests\"\n               ReferencedContainer = \"container:PromiseKit.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n         <TestableReference\n            skipped = \"NO\"\n            parallelizable = \"YES\"\n            testExecutionOrdering = \"random\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"631411321D59795700E24B9E\"\n               BuildableName = \"PMKBridgeTests.xctest\"\n               BlueprintName = \"PMKBridgeTests\"\n               ReferencedContainer = \"container:PromiseKit.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n         <TestableReference\n            skipped = \"NO\"\n            parallelizable = \"YES\"\n            testExecutionOrdering = \"random\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"633027E0203CC0060037E136\"\n               BuildableName = \"PMKDeprecatedTests.xctest\"\n               BlueprintName = \"PMKDeprecatedTests\"\n               ReferencedContainer = \"container:PromiseKit.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n         <TestableReference\n            skipped = \"NO\"\n            parallelizable = \"YES\"\n            testExecutionOrdering = \"random\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"C0244E4E2047A6CB00ACB4AC\"\n               BuildableName = \"PMKJSA+Tests.xctest\"\n               BlueprintName = \"PMKJSA+Tests\"\n               ReferencedContainer = \"container:PromiseKit.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"63B0AC561D595E1B00FA21D9\"\n            BuildableName = \"PromiseKit.framework\"\n            BlueprintName = \"PromiseKit\"\n            ReferencedContainer = \"container:PromiseKit.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"63B0AC561D595E1B00FA21D9\"\n            BuildableName = \"PromiseKit.framework\"\n            BlueprintName = \"PromiseKit\"\n            ReferencedContainer = \"container:PromiseKit.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "README.md",
    "content": "![PromiseKit](../gh-pages/public/img/logo-tight.png)\n\n[![badge-pod][]][cocoapods] ![badge-languages][] ![badge-pms][] ![badge-platforms][] [![codecov](https://codecov.io/gh/mxcl/PromiseKit/branch/master/graph/badge.svg?token=wHSAz7N8WA)](https://codecov.io/gh/mxcl/PromiseKit)\n\n---\n\nPromises simplify asynchronous programming, freeing you up to focus on the more\nimportant things. They are easy to learn, easy to master and result in clearer,\nmore readable code. Your co-workers will thank you.\n\n```swift\nUIApplication.shared.isNetworkActivityIndicatorVisible = true\n\nlet fetchImage = URLSession.shared.dataTask(.promise, with: url).compactMap{ UIImage(data: $0.data) }\nlet fetchLocation = CLLocationManager.requestLocation().lastValue\n\nfirstly {\n    when(fulfilled: fetchImage, fetchLocation)\n}.done { image, location in\n    self.imageView.image = image\n    self.label.text = \"\\(location)\"\n}.ensure {\n    UIApplication.shared.isNetworkActivityIndicatorVisible = false\n}.catch { error in\n    self.show(UIAlertController(for: error), sender: self)\n}\n```\n\nPromiseKit is a thoughtful and complete implementation of promises for any\nplatform that has a `swiftc`. It has *excellent* Objective-C bridging and\n*delightful* specializations for iOS, macOS, tvOS and watchOS. It is a top-100\npod used in many of the most popular apps in the world.\n\n[![codecov](https://codecov.io/gh/mxcl/PromiseKit/branch/master/graph/badge.svg)](https://codecov.io/gh/mxcl/PromiseKit)\n\n# Quick Start\n\nIn your [Podfile]:\n\n```ruby\nuse_frameworks!\n\ntarget \"Change Me!\" do\n  pod \"PromiseKit\", \"~> 8\"\nend\n```\n\nPromiseKit 8 supports recent Xcodes (13+). Some Podspecs were\n[dropped as a result](https://github.com/mxcl/PromiseKit/pull/1318).\nPull requests are welcome.\n\nPromiseKit 6, 5 and 4 support Xcode 8.3, 9.x and 10.0; Swift 3.1,\n3.2, 3.3, 3.4, 4.0, 4.1, 4.2, 4.3 and 5.0 (development snapshots); iOS, macOS,\ntvOS, watchOS, Linux and Android; CocoaPods, Carthage and SwiftPM;\n([CI Matrix](https://travis-ci.org/mxcl/PromiseKit)).\n\nFor Carthage, SwiftPM, Accio, etc., or for instructions when using older Swifts or Xcodes, see our [Installation Guide]. We recommend\n[Carthage](https://github.com/Carthage/Carthage) or\n[Accio](https://github.com/JamitLabs/Accio).\n\n# PromiseKit and Swift 5.5+ Async/Await\n\nAs of Swift 5.5, the Swift language now offers support for [built-in concurrency with async / await](https://docs.swift.org/swift-book/LanguageGuide/Concurrency.html).  See [Async+](https://github.com/async-plus/async-plus) for a port of PromiseKit's most useful patterns to this new paradigm.\n\n# Professionally Supported PromiseKit is Now Available\n\nTideLift gives software development teams a single source for purchasing\nand maintaining their software, with professional grade assurances from\nthe experts who know it best, while seamlessly integrating with existing\ntools.\n\n[Get Professional Support for PromiseKit with TideLift](https://tidelift.com/subscription/pkg/cocoapods-promisekit?utm_source=cocoapods-promisekit&utm_medium=referral&utm_campaign=readme).\n\n\n# Documentation\n\n* Handbook\n  * [Getting Started](Documentation/GettingStarted.md)\n  * [Promises: Common Patterns](Documentation/CommonPatterns.md)\n  * [Frequently Asked Questions](Documentation/FAQ.md)\n* Manual\n  * [Installation Guide](Documentation/Installation.md)\n  * [Objective-C Guide](Documentation/ObjectiveC.md)\n  * [Troubleshooting](Documentation/Troubleshooting.md) (e.g., solutions to common compile errors)\n  * [Appendix](Documentation/Appendix.md)\n* [API Reference](https://mxcl.dev/PromiseKit/reference/v6/Classes/Promise.html)\n\n# Extensions\n\nPromises are only as useful as the asynchronous tasks they represent. Thus, we\nhave converted (almost) all of Apple’s APIs to promises. The default CocoaPod\nprovides Promises and the extensions for Foundation and UIKit. The other\nextensions are available by specifying additional subspecs in your `Podfile`,\ne.g.:\n\n```ruby\npod \"PromiseKit/MapKit\"          # MKDirections().calculate().then { /*…*/ }\npod \"PromiseKit/CoreLocation\"    # CLLocationManager.requestLocation().then { /*…*/ }\n```\n\nAll our extensions are separate repositories at the [PromiseKit organization].\n\n## I don't want the extensions!\n\nThen don’t have them:\n\n```ruby\npod \"PromiseKit/CorePromise\", \"~> 8\"\n```\n\n> *Note:* Carthage installations come with no extensions by default.\n\n## Networking\n\nPromise chains commonly start with a network operation. Thus, we offer\nextensions for `URLSession`:\n\n```swift\n// pod 'PromiseKit/Foundation'  # https://github.com/PromiseKit/Foundation\n\nfirstly {\n    URLSession.shared.dataTask(.promise, with: try makeUrlRequest()).validate()\n    // ^^ we provide `.validate()` so that eg. 404s get converted to errors\n}.map {\n    try JSONDecoder().decode(Foo.self, with: $0.data)\n}.done { foo in\n    //…\n}.catch { error in\n    //…\n}\n\nfunc makeUrlRequest() throws -> URLRequest {\n    var rq = URLRequest(url: url)\n    rq.httpMethod = \"POST\"\n    rq.addValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\n    rq.addValue(\"application/json\", forHTTPHeaderField: \"Accept\")\n    rq.httpBody = try JSONEncoder().encode(obj)\n    return rq\n}\n```\n\nSupport for Alamofire is welcome, please submit a PR.\n\n\n# Support\n\nPlease check our [Troubleshooting Guide](Documentation/Troubleshooting.md), and\nif after that you still have a question, ask at our [Gitter chat channel] or on [our bug tracker].\n\n## Security & Vulnerability Reporting or Disclosure\n\nhttps://tidelift.com/security\n\n\n[badge-pod]: https://img.shields.io/cocoapods/v/PromiseKit.svg?label=version\n[badge-pms]: https://img.shields.io/badge/supports-CocoaPods%20%7C%20Carthage%20%7C%20Accio%20%7C%20SwiftPM-green.svg\n[badge-languages]: https://img.shields.io/badge/languages-Swift%20%7C%20ObjC-orange.svg\n[badge-platforms]: https://img.shields.io/badge/platforms-macOS%20%7C%20iOS%20%7C%20watchOS%20%7C%20tvOS%20%7C%20Linux-lightgrey.svg\n[badge-mit]: https://img.shields.io/badge/license-MIT-blue.svg\n[OMGHTTPURLRQ]: https://github.com/PromiseKit/OMGHTTPURLRQ\n[Alamofire]: http://github.com/PromiseKit/Alamofire-\n[PromiseKit organization]: https://github.com/PromiseKit\n[Gitter chat channel]: https://gitter.im/mxcl/PromiseKit\n[our bug tracker]: https://github.com/mxcl/PromiseKit/issues/new\n[Podfile]: https://guides.cocoapods.org/syntax/podfile.html\n[PMK6]: http://mxcl.dev/PromiseKit/news/2018/02/PromiseKit-6.0-Released/\n[Installation Guide]: Documentation/Installation.md\n[badge-travis]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=master\n[travis]: https://travis-ci.org/mxcl/PromiseKit\n[cocoapods]: https://cocoapods.org/pods/PromiseKit\n"
  },
  {
    "path": "Sources/AnyPromise+Private.h",
    "content": "@import Foundation.NSError;\n@import Foundation.NSPointerArray;\n\n#if TARGET_OS_IPHONE\n    #define NSPointerArrayMake(N) ({ \\\n        NSPointerArray *aa = [NSPointerArray strongObjectsPointerArray]; \\\n        aa.count = N; \\\n        aa; \\\n    })\n#else\n    static inline NSPointerArray * __nonnull NSPointerArrayMake(NSUInteger count) {\n      #pragma clang diagnostic push\n      #pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n        NSPointerArray *aa = [[NSPointerArray class] respondsToSelector:@selector(strongObjectsPointerArray)]\n            ? [NSPointerArray strongObjectsPointerArray]\n            : [NSPointerArray pointerArrayWithStrongObjects];\n      #pragma clang diagnostic pop\n        aa.count = count;\n        return aa;\n    }\n#endif\n\n#define IsError(o) [o isKindOfClass:[NSError class]]\n#define IsPromise(o) [o isKindOfClass:[AnyPromise class]]\n\n#import \"AnyPromise.h\"\n\n@class PMKArray;\n\n@interface AnyPromise ()\n- (void)__pipe:(void(^ __nonnull)(__nullable id))block NS_REFINED_FOR_SWIFT;\n@end\n"
  },
  {
    "path": "Sources/AnyPromise.h",
    "content": "#import <Foundation/Foundation.h>\n#import <dispatch/dispatch.h>\n#import <PromiseKit/fwd.h>\n\n/// INTERNAL DO NOT USE\n@class __AnyPromise;\n\n/// Provided to simplify some usage sites\ntypedef void (^PMKResolver)(id __nullable) NS_REFINED_FOR_SWIFT;\n\n\n/// An Objective-C implementation of the promise pattern.\n@interface AnyPromise: NSObject\n\n/**\n Create a new promise that resolves with the provided block.\n\n Use this method when wrapping asynchronous code that does *not* use promises so that this code can be used in promise chains.\n\n If `resolve` is called with an `NSError` object, the promise is rejected, otherwise the promise is fulfilled.\n\n Don’t use this method if you already have promises! Instead, just return your promise.\n\n Should you need to fulfill a promise but have no sensical value to use: your promise is a `void` promise: fulfill with `nil`.\n\n The block you pass is executed immediately on the calling thread.\n\n - Parameter block: The provided block is immediately executed, inside the block call `resolve` to resolve this promise and cause any attached handlers to execute. If you are wrapping a delegate-based system, we recommend instead to use: initWithResolver:\n - Returns: A new promise.\n - Warning: Resolving a promise with `nil` fulfills it.\n - SeeAlso: https://github.com/mxcl/PromiseKit/blob/master/Documentation/GettingStarted.md#making-promises\n - SeeAlso: https://github.com/mxcl/PromiseKit/blob/master/Documentation/CommonPatterns.md#wrapping-delegate-systems\n */\n+ (instancetype __nonnull)promiseWithResolverBlock:(void (^ __nonnull)(__nonnull PMKResolver))resolveBlock NS_REFINED_FOR_SWIFT;\n\n\n/// INTERNAL DO NOT USE\n- (instancetype __nonnull)initWith__D:(__AnyPromise * __nonnull)d;\n\n/**\n Creates a resolved promise.\n\n When developing your own promise systems, it is occasionally useful to be able to return an already resolved promise.\n\n - Parameter value: The value with which to resolve this promise. Passing an `NSError` will cause the promise to be rejected, passing an AnyPromise will return a new AnyPromise bound to that promise, otherwise the promise will be fulfilled with the value passed.\n - Returns: A resolved promise.\n */\n+ (instancetype __nonnull)promiseWithValue:(__nullable id)value NS_REFINED_FOR_SWIFT;\n\n/**\n The value of the asynchronous task this promise represents.\n\n A promise has `nil` value if the asynchronous task it represents has not finished. If the value is `nil` the promise is still `pending`.\n\n - Warning: *Note* Our Swift variant’s value property returns nil if the promise is rejected where AnyPromise will return the error object. This fits with the pattern where AnyPromise is not strictly typed and is more dynamic, but you should be aware of the distinction.\n\n - Note: If the AnyPromise was fulfilled with a `PMKManifold`, returns only the first fulfillment object.\n\n - Returns: The value with which this promise was resolved or `nil` if this promise is pending.\n */\n@property (nonatomic, readonly) __nullable id value NS_REFINED_FOR_SWIFT;\n\n/// - Returns: if the promise is pending resolution.\n@property (nonatomic, readonly) BOOL pending NS_REFINED_FOR_SWIFT;\n\n/// - Returns: if the promise is resolved and fulfilled.\n@property (nonatomic, readonly) BOOL fulfilled NS_REFINED_FOR_SWIFT;\n\n/// - Returns: if the promise is resolved and rejected.\n@property (nonatomic, readonly) BOOL rejected NS_REFINED_FOR_SWIFT;\n\n\n/**\n The provided block is executed when its receiver is fulfilled.\n\n If you provide a block that takes a parameter, the value of the receiver will be passed as that parameter.\n\n    [NSURLSession GET:url].then(^(NSData *data){\n        // do something with data\n    });\n\n @return A new promise that is resolved with the value returned from the provided block. For example:\n\n    [NSURLSession GET:url].then(^(NSData *data){\n        return data.length;\n    }).then(^(NSNumber *number){\n        //…\n    });\n\n @warning *Important* The block passed to `then` may take zero, one, two or three arguments, and return an object or return nothing. This flexibility is why the method signature for then is `id`, which means you will not get completion for the block parameter, and must type it yourself. It is safe to type any block syntax here, so to start with try just: `^{}`.\n\n @warning *Important* If an `NSError` or `NSString` is thrown inside your block, or you return an `NSError` object the next `Promise` will be rejected. See `catch` for documentation on error handling.\n\n @warning *Important* `then` is always executed on the main queue.\n\n @see thenOn\n @see thenInBackground\n*/\n- (AnyPromise * __nonnull (^ __nonnull)(id __nonnull))then NS_REFINED_FOR_SWIFT;\n\n\n/**\n The provided block is executed on the default queue when the receiver is fulfilled.\n\n This method is provided as a convenience for `thenOn`.\n\n @see then\n @see thenOn\n*/\n- (AnyPromise * __nonnull(^ __nonnull)(id __nonnull))thenInBackground NS_REFINED_FOR_SWIFT;\n\n/**\n The provided block is executed on the dispatch queue of your choice when the receiver is fulfilled.\n\n @see then\n @see thenInBackground\n*/\n- (AnyPromise * __nonnull(^ __nonnull)(dispatch_queue_t __nonnull, id __nonnull))thenOn NS_REFINED_FOR_SWIFT;\n\n#ifndef __cplusplus\n/**\n The provided block is executed when the receiver is rejected.\n\n Provide a block of form `^(NSError *){}` or simply `^{}`. The parameter has type `id` to give you the freedom to choose either.\n\n The provided block always runs on the main queue.\n\n @warning *Note* Cancellation errors are not caught.\n\n @warning *Note* Since catch is a c++ keyword, this method is not available in Objective-C++ files. Instead use catchOn.\n\n @see catchOn\n @see catchInBackground\n*/\n- (AnyPromise * __nonnull(^ __nonnull)(id __nonnull))catch NS_REFINED_FOR_SWIFT;\n#endif\n\n/**\n The provided block is executed when the receiver is rejected.\n\n Provide a block of form `^(NSError *){}` or simply `^{}`. The parameter has type `id` to give you the freedom to choose either.\n\n The provided block always runs on the global background queue.\n\n @warning *Note* Cancellation errors are not caught.\n\n @warning *Note* Since catch is a c++ keyword, this method is not available in Objective-C++ files. Instead use catchWithPolicy.\n\n @see catch\n @see catchOn\n */\n- (AnyPromise * __nonnull(^ __nonnull)(id __nonnull))catchInBackground NS_REFINED_FOR_SWIFT;\n\n\n/**\n The provided block is executed when the receiver is rejected.\n\n Provide a block of form `^(NSError *){}` or simply `^{}`. The parameter has type `id` to give you the freedom to choose either.\n\n The provided block always runs on queue provided.\n\n @warning *Note* Cancellation errors are not caught.\n\n @see catch\n @see catchInBackground\n */\n- (AnyPromise * __nonnull(^ __nonnull)(dispatch_queue_t __nonnull, id __nonnull))catchOn NS_REFINED_FOR_SWIFT;\n\n/**\n The provided block is executed when the receiver is resolved.\n\n The provided block always runs on the main queue.\n\n @see ensureOn\n*/\n- (AnyPromise * __nonnull(^ __nonnull)(dispatch_block_t __nonnull))ensure NS_REFINED_FOR_SWIFT;\n\n/**\n The provided block is executed on the dispatch queue of your choice when the receiver is resolved.\n\n @see ensure\n */\n- (AnyPromise * __nonnull(^ __nonnull)(dispatch_queue_t __nonnull, dispatch_block_t __nonnull))ensureOn NS_REFINED_FOR_SWIFT;\n\n/**\n The provided block is executed on the global background queue when the receiver is resolved.\n\n @see ensure\n */\n- (AnyPromise * __nonnull(^ __nonnull)(dispatch_block_t __nonnull))ensureInBackground NS_REFINED_FOR_SWIFT;\n\n/**\n Wait until the promise is resolved.\n\n @return Value if fulfilled or error if rejected.\n */\n- (id __nullable)wait NS_REFINED_FOR_SWIFT;\n\n/**\n Create a new promise with an associated resolver.\n\n Use this method when wrapping asynchronous code that does *not* use\n promises so that this code can be used in promise chains. Generally,\n prefer `promiseWithResolverBlock:` as the resulting code is more elegant.\n\n     PMKResolver resolve;\n     AnyPromise *promise = [[AnyPromise alloc] initWithResolver:&resolve];\n\n     // later\n     resolve(@\"foo\");\n\n @param resolver A reference to a block pointer of PMKResolver type.\n You can then call your resolver to resolve this promise.\n\n @return A new promise.\n\n @warning *Important* The resolver strongly retains the promise.\n\n @see promiseWithResolverBlock:\n*/\n- (instancetype __nonnull)initWithResolver:(PMKResolver __strong __nonnull * __nonnull)resolver NS_REFINED_FOR_SWIFT;\n\n/**\n Unavailable methods\n */\n\n- (instancetype __nonnull)init __attribute__((unavailable(\"It is illegal to create an unresolvable promise.\")));\n+ (instancetype __nonnull)new __attribute__((unavailable(\"It is illegal to create an unresolvable promise.\")));\n- (AnyPromise * __nonnull(^ __nonnull)(dispatch_block_t __nonnull))always __attribute__((unavailable(\"See -ensure\")));\n- (AnyPromise * __nonnull(^ __nonnull)(dispatch_block_t __nonnull))alwaysOn __attribute__((unavailable(\"See -ensureOn\")));\n- (AnyPromise * __nonnull(^ __nonnull)(dispatch_block_t __nonnull))finally __attribute__((unavailable(\"See -ensure\")));\n- (AnyPromise * __nonnull(^ __nonnull)(dispatch_block_t __nonnull, dispatch_block_t __nonnull))finallyOn __attribute__((unavailable(\"See -ensureOn\")));\n\n@end\n\n\ntypedef void (^PMKAdapter)(id __nullable, NSError * __nullable) NS_REFINED_FOR_SWIFT;\ntypedef void (^PMKIntegerAdapter)(NSInteger, NSError * __nullable) NS_REFINED_FOR_SWIFT;\ntypedef void (^PMKBooleanAdapter)(BOOL, NSError * __nullable) NS_REFINED_FOR_SWIFT;\n\n\n@interface AnyPromise (Adapters)\n\n/**\n Create a new promise by adapting an existing asynchronous system.\n\n The pattern of a completion block that passes two parameters, the first\n the result and the second an `NSError` object is so common that we\n provide this convenience adapter to make wrapping such systems more\n elegant.\n\n    return [PMKPromise promiseWithAdapterBlock:^(PMKAdapter adapter){\n        PFQuery *query = [PFQuery …];\n        [query findObjectsInBackgroundWithBlock:adapter];\n    }];\n\n @warning *Important* If both parameters are nil, the promise fulfills,\n if both are non-nil the promise rejects. This is per the convention.\n\n @see https://github.com/mxcl/PromiseKit/blob/master/Documentation/GettingStarted.md#making-promises\n */\n+ (instancetype __nonnull)promiseWithAdapterBlock:(void (^ __nonnull)(PMKAdapter __nonnull adapter))block NS_REFINED_FOR_SWIFT;\n\n/**\n Create a new promise by adapting an existing asynchronous system.\n\n Adapts asynchronous systems that complete with `^(NSInteger, NSError *)`.\n NSInteger will cast to enums provided the enum has been wrapped with\n `NS_ENUM`. All of Apple’s enums are, so if you find one that hasn’t you\n may need to make a pull-request.\n\n @see promiseWithAdapter\n */\n+ (instancetype __nonnull)promiseWithIntegerAdapterBlock:(void (^ __nonnull)(PMKIntegerAdapter __nonnull adapter))block NS_REFINED_FOR_SWIFT;\n\n/**\n Create a new promise by adapting an existing asynchronous system.\n\n Adapts asynchronous systems that complete with `^(BOOL, NSError *)`.\n\n @see promiseWithAdapter\n */\n+ (instancetype __nonnull)promiseWithBooleanAdapterBlock:(void (^ __nonnull)(PMKBooleanAdapter __nonnull adapter))block NS_REFINED_FOR_SWIFT;\n\n@end\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n Whenever resolving a promise you may resolve with a tuple, eg.\n returning from a `then` or `catch` handler or resolving a new promise.\n\n Consumers of your Promise are not compelled to consume any arguments and\n in fact will often only consume the first parameter. Thus ensure the\n order of parameters is: from most-important to least-important.\n\n Currently PromiseKit limits you to THREE parameters to the manifold.\n*/\n#define PMKManifold(...) __PMKManifold(__VA_ARGS__, 3, 2, 1)\n#define __PMKManifold(_1, _2, _3, N, ...) __PMKArrayWithCount(N, _1, _2, _3)\nextern id __nonnull __PMKArrayWithCount(NSUInteger, ...);\n\n#ifdef __cplusplus\n}   // Extern C\n#endif\n\n\n\n\n__attribute__((unavailable(\"See AnyPromise\")))\n@interface PMKPromise\n@end\n"
  },
  {
    "path": "Sources/AnyPromise.m",
    "content": "#if __has_include(\"PromiseKit-Swift.h\")\n    #import \"PromiseKit-Swift.h\"\n#else\n    #import <PromiseKit/PromiseKit-Swift.h>\n#endif\n#import \"PMKCallVariadicBlock.m\"\n#import \"AnyPromise+Private.h\"\n#import \"AnyPromise.h\"\n\nNSString *const PMKErrorDomain = @\"PMKErrorDomain\";\n\n\n@implementation AnyPromise {\n    __AnyPromise *d;\n}\n\n- (instancetype)initWith__D:(__AnyPromise *)dd {\n    self = [super init];\n    if (self) self->d = dd;\n    return self;\n}\n\n- (instancetype)initWithResolver:(PMKResolver __strong *)resolver {\n    self = [super init];\n    if (self)\n        d = [[__AnyPromise alloc] initWithResolver:^(void (^resolve)(id)) {\n            *resolver = resolve;\n        }];\n    return self;\n}\n\n+ (instancetype)promiseWithResolverBlock:(void (^)(PMKResolver _Nonnull))resolveBlock {\n    id d = [[__AnyPromise alloc] initWithResolver:resolveBlock];\n    return [[self alloc] initWith__D:d];\n}\n\n+ (instancetype)promiseWithValue:(id)value {\n    //TODO provide a more efficient route for sealed promises\n    id d = [[__AnyPromise alloc] initWithResolver:^(void (^resolve)(id)) {\n        resolve(value);\n    }];\n    return [[self alloc] initWith__D:d];\n}\n\n//TODO remove if possible, but used by when.m\n- (void)__pipe:(void (^)(id _Nullable))block {\n    [d __pipe:block];\n}\n\n//NOTE used by AnyPromise.swift\n- (id)__d {\n    return d;\n}\n\n- (AnyPromise *(^)(id))then {\n    return ^(id block) {\n        return [self->d __thenOn:dispatch_get_main_queue() execute:^(id obj) {\n            return PMKCallVariadicBlock(block, obj);\n        }];\n    };\n}\n\n- (AnyPromise *(^)(dispatch_queue_t, id))thenOn {\n    return ^(dispatch_queue_t queue, id block) {\n        return [self->d __thenOn:queue execute:^(id obj) {\n            return PMKCallVariadicBlock(block, obj);\n        }];\n    };\n}\n\n- (AnyPromise *(^)(id))thenInBackground {\n    return ^(id block) {\n        return [self->d __thenOn:dispatch_get_global_queue(0, 0) execute:^(id obj) {\n            return PMKCallVariadicBlock(block, obj);\n        }];\n    };\n}\n\n- (AnyPromise *(^)(dispatch_queue_t, id))catchOn {\n    return ^(dispatch_queue_t q, id block) {\n        return [self->d __catchOn:q execute:^(id obj) {\n            return PMKCallVariadicBlock(block, obj);\n        }];\n    };\n}\n\n- (AnyPromise *(^)(id))catch {\n    return ^(id block) {\n        return [self->d __catchOn:dispatch_get_main_queue() execute:^(id obj) {\n            return PMKCallVariadicBlock(block, obj);\n        }];\n    };\n}\n\n- (AnyPromise *(^)(id))catchInBackground {\n    return ^(id block) {\n        return [self->d __catchOn:dispatch_get_global_queue(0, 0) execute:^(id obj) {\n            return PMKCallVariadicBlock(block, obj);\n        }];\n    };\n}\n\n- (AnyPromise *(^)(dispatch_block_t))ensure {\n    return ^(dispatch_block_t block) {\n        return [self->d __ensureOn:dispatch_get_main_queue() execute:block];\n    };\n}\n\n- (AnyPromise *(^)(dispatch_queue_t, dispatch_block_t))ensureOn {\n    return ^(dispatch_queue_t queue, dispatch_block_t block) {\n        return [self->d __ensureOn:queue execute:block];\n    };\n}\n\n- (AnyPromise *(^)(dispatch_block_t))ensureInBackground {\n    return ^(dispatch_block_t block) {\n        return [self->d __ensureOn:dispatch_get_global_queue(QOS_CLASS_UNSPECIFIED, 0) execute:block];\n    };\n}\n\n- (id)wait {\n    return [d __wait];\n}\n\n- (BOOL)pending {\n    return [[d valueForKey:@\"__pending\"] boolValue];\n}\n\n- (BOOL)rejected {\n    return IsError([d __value]);\n}\n\n- (BOOL)fulfilled {\n    return !self.rejected;\n}\n\n- (id)value {\n    id obj = [d __value];\n\n    if ([obj isKindOfClass:[PMKArray class]]) {\n        return obj[0];\n    } else {\n        return obj;\n    }\n}\n\n@end\n\n\n\n@implementation AnyPromise (Adapters)\n\n+ (instancetype)promiseWithAdapterBlock:(void (^)(PMKAdapter))block {\n    return [self promiseWithResolverBlock:^(PMKResolver resolve) {\n        block(^(id value, id error){\n            resolve(error ?: value);\n        });\n    }];\n}\n\n+ (instancetype)promiseWithIntegerAdapterBlock:(void (^)(PMKIntegerAdapter))block {\n    return [self promiseWithResolverBlock:^(PMKResolver resolve) {\n        block(^(NSInteger value, id error){\n            if (error) {\n                resolve(error);\n            } else {\n                resolve(@(value));\n            }\n        });\n    }];\n}\n\n+ (instancetype)promiseWithBooleanAdapterBlock:(void (^)(PMKBooleanAdapter adapter))block {\n    return [self promiseWithResolverBlock:^(PMKResolver resolve) {\n        block(^(BOOL value, id error){\n            if (error) {\n                resolve(error);\n            } else {\n                resolve(@(value));\n            }\n        });\n    }];\n}\n\n@end\n"
  },
  {
    "path": "Sources/AnyPromise.swift",
    "content": "import Foundation\n\n/**\n __AnyPromise is an implementation detail.\n\n Because of how ObjC/Swift compatibility work we have to compose our AnyPromise\n with this internal object, however this is still part of the public interface.\n Sadly. Please don’t use it.\n*/\n@objc(__AnyPromise) public class __AnyPromise: NSObject {\n    fileprivate let box: Box<Any?>\n\n    @objc public init(resolver body: (@escaping (Any?) -> Void) -> Void) {\n        box = EmptyBox<Any?>()\n        super.init()\n        body {\n            if let p = $0 as? AnyPromise {\n                p.d.__pipe(self.box.seal)\n            } else {\n                self.box.seal($0)\n            }\n        }\n    }\n\n    @objc public func __thenOn(_ q: DispatchQueue, execute: @escaping (Any?) -> Any?) -> AnyPromise {\n        return AnyPromise(__D: __AnyPromise(resolver: { resolve in\n            self.__pipe { obj in\n                if !(obj is NSError) {\n                    q.async {\n                        resolve(execute(obj))\n                    }\n                } else {\n                    resolve(obj)\n                }\n            }\n        }))\n    }\n\n    @objc public func __catchOn(_ q: DispatchQueue, execute: @escaping (Any?) -> Any?) -> AnyPromise {\n        return AnyPromise(__D: __AnyPromise(resolver: { resolve in\n            self.__pipe { obj in\n                if obj is NSError {\n                    q.async {\n                        resolve(execute(obj))\n                    }\n                } else {\n                    resolve(obj)\n                }\n            }\n        }))\n    }\n\n    @objc public func __ensureOn(_ q: DispatchQueue, execute: @escaping () -> Void) -> AnyPromise {\n        return AnyPromise(__D: __AnyPromise(resolver: { resolve in\n            self.__pipe { obj in\n                q.async {\n                    execute()\n                    resolve(obj)\n                }\n            }\n        }))\n    }\n\n    @objc public func __wait() -> Any? {\n        if Thread.isMainThread {\n            conf.logHandler(.waitOnMainThread)\n        }\n        \n        var result = __value\n        \n        if result == nil {\n            let group = DispatchGroup()\n            group.enter()\n            self.__pipe { obj in\n                result = obj\n                group.leave()\n            }\n            group.wait()\n        }\n        \n        return result\n    }\n \n    /// Internal, do not use! Some behaviors undefined.\n    @objc public func __pipe(_ to: @escaping (Any?) -> Void) {\n        let to = { (obj: Any?) -> Void in\n            if obj is NSError {\n                to(obj)  // or we cannot determine if objects are errors in objc land\n            } else {\n                to(obj)\n            }\n        }\n        switch box.inspect() {\n        case .pending:\n            box.inspect {\n                switch $0 {\n                case .pending(let handlers):\n                    handlers.append { obj in\n                        to(obj)\n                    }\n                case .resolved(let obj):\n                    to(obj)\n                }\n            }\n        case .resolved(let obj):\n            to(obj)\n        }\n    }\n\n    @objc public var __value: Any? {\n        switch box.inspect() {\n        case .resolved(let obj):\n            return obj\n        default:\n            return nil\n        }\n    }\n\n    @objc public var __pending: Bool {\n        switch box.inspect() {\n        case .pending:\n            return true\n        case .resolved:\n            return false\n        }\n    }\n}\n\nextension AnyPromise: Thenable, CatchMixin {\n\n    /// - Returns: A new `AnyPromise` bound to a `Promise<Any>`.\n    public convenience init<U: Thenable>(_ bridge: U) {\n        self.init(__D: __AnyPromise(resolver: { resolve in\n            bridge.pipe {\n                switch $0 {\n                case .rejected(let error):\n                    resolve(error as NSError)\n                case .fulfilled(let value):\n                    resolve(value)\n                }\n            }\n        }))\n    }\n\n    public func pipe(to body: @escaping (Result<Any?>) -> Void) {\n\n        func fulfill() {\n            // calling through to the ObjC `value` property unwraps (any) PMKManifold\n            // and considering this is the Swift pipe; we want that.\n            body(.fulfilled(self.value(forKey: \"value\")))\n        }\n\n        switch box.inspect() {\n        case .pending:\n            box.inspect {\n                switch $0 {\n                case .pending(let handlers):\n                    handlers.append {\n                        if let error = $0 as? Error {\n                            body(.rejected(error))\n                        } else {\n                            fulfill()\n                        }\n                    }\n                case .resolved(let error as Error):\n                    body(.rejected(error))\n                case .resolved:\n                    fulfill()\n                }\n            }\n        case .resolved(let error as Error):\n            body(.rejected(error))\n        case .resolved:\n            fulfill()\n        }\n    }\n\n    fileprivate var d: __AnyPromise {\n        return value(forKey: \"__d\") as! __AnyPromise\n    }\n\n    var box: Box<Any?> {\n        return d.box\n    }\n\n    public var result: Result<Any?>? {\n        guard let value = __value else {\n            return nil\n        }\n        if let error = value as? Error {\n            return .rejected(error)\n        } else {\n            return .fulfilled(value)\n        }\n    }\n\n    public typealias T = Any?\n}\n\n\n#if swift(>=3.1)\npublic extension Promise where T == Any? {\n    convenience init(_ anyPromise: AnyPromise) {\n        self.init {\n            anyPromise.pipe(to: $0.resolve)\n        }\n    }\n}\n#else\nextension AnyPromise {\n    public func asPromise() -> Promise<Any?> {\n        return Promise(.pending, resolver: { resolve in\n            pipe { result in\n                switch result {\n                case .rejected(let error):\n                    resolve.reject(error)\n                case .fulfilled(let obj):\n                    resolve.fulfill(obj)\n                }\n            }\n        })\n    }\n}\n#endif\n"
  },
  {
    "path": "Sources/Async.swift",
    "content": "#if swift(>=5.5)\n#if canImport(_Concurrency)\n@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)\npublic extension Guarantee {\n    func async() async -> T {\n        await withCheckedContinuation { continuation in\n            done { value in\n                continuation.resume(returning: value)\n            }\n        }\n    }\n}\n\n@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)\npublic extension Promise {\n    func async() async throws -> T {\n        try await withCheckedThrowingContinuation { continuation in\n            done { value in\n                continuation.resume(returning: value)\n            }.catch(policy: .allErrors) { error in\n                continuation.resume(throwing: error)\n            }\n        }\n    }\n}\n#endif\n#endif\n\n"
  },
  {
    "path": "Sources/Box.swift",
    "content": "import Dispatch\n\nenum Sealant<R> {\n    case pending(Handlers<R>)\n    case resolved(R)\n}\n\nfinal class Handlers<R> {\n    var bodies: [(R) -> Void] = []\n    func append(_ item: @escaping(R) -> Void) { bodies.append(item) }\n}\n\n/// - Remark: not protocol ∵ http://www.russbishop.net/swift-associated-types-cont\nclass Box<T> {\n    func inspect() -> Sealant<T> { fatalError() }\n    func inspect(_: (Sealant<T>) -> Void) { fatalError() }\n    func seal(_: T) {}\n}\n\nfinal class SealedBox<T>: Box<T> {\n    let value: T\n\n    init(value: T) {\n        self.value = value\n    }\n\n    override func inspect() -> Sealant<T> {\n        return .resolved(value)\n    }\n}\n\nclass EmptyBox<T>: Box<T> {\n    private var sealant = Sealant<T>.pending(.init())\n    private let barrier = DispatchQueue(label: \"org.promisekit.barrier\", attributes: .concurrent)\n\n    override func seal(_ value: T) {\n        var handlers: Handlers<T>!\n        barrier.sync(flags: .barrier) {\n            guard case .pending(let _handlers) = self.sealant else {\n                return  // already fulfilled!\n            }\n            handlers = _handlers\n            self.sealant = .resolved(value)\n        }\n\n        //FIXME we are resolved so should `pipe(to:)` be called at this instant, “thens are called in order” would be invalid\n        //NOTE we don’t do this in the above `sync` because that could potentially deadlock\n        //THOUGH since `then` etc. typically invoke after a run-loop cycle, this issue is somewhat less severe\n\n        if let handlers = handlers {\n            handlers.bodies.forEach{ $0(value) }\n        }\n\n        //TODO solution is an unfortunate third state “sealed” where then's get added\n        // to a separate handler pool for that state\n        // any other solution has potential races\n    }\n\n    override func inspect() -> Sealant<T> {\n        var rv: Sealant<T>!\n        barrier.sync {\n            rv = self.sealant\n        }\n        return rv\n    }\n\n    override func inspect(_ body: (Sealant<T>) -> Void) {\n        var sealed = false\n        barrier.sync(flags: .barrier) {\n            switch sealant {\n            case .pending:\n                // body will append to handlers, so we must stay barrier’d\n                body(sealant)\n            case .resolved:\n                sealed = true\n            }\n        }\n        if sealed {\n            // we do this outside the barrier to prevent potential deadlocks\n            // it's safe because we never transition away from this state\n            body(sealant)\n        }\n    }\n}\n\n\nextension Optional where Wrapped: DispatchQueue {\n    @inline(__always)\n    func async(flags: DispatchWorkItemFlags?, _ body: @escaping() -> Void) {\n        switch self {\n        case .none:\n            body()\n        case .some(let q):\n            if let flags = flags {\n                q.async(flags: flags, execute: body)\n            } else {\n                q.async(execute: body)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Sources/Catchable.swift",
    "content": "import Dispatch\n\n/// Provides `catch` and `recover` to your object that conforms to `Thenable`\npublic protocol CatchMixin: Thenable\n{}\n\npublic extension CatchMixin {\n    \n    /**\n     The provided closure executes when this promise rejects.\n     \n     Rejecting a promise cascades: rejecting all subsequent promises (unless\n     recover is invoked) thus you will typically place your catch at the end\n     of a chain. Often utility promises will not have a catch, instead\n     delegating the error handling to the caller.\n     \n     - Parameter on: The queue to which the provided closure dispatches.\n     - Parameter policy: The default policy does not execute your handler for cancellation errors.\n     - Parameter execute: The handler to execute if this promise is rejected.\n     - Returns: A promise finalizer.\n     - SeeAlso: [Cancellation](https://github.com/mxcl/PromiseKit/blob/master/Documentation/CommonPatterns.md#cancellation)\n     */\n    @discardableResult\n    func `catch`(on: DispatchQueue? = conf.Q.return, flags: DispatchWorkItemFlags? = nil, policy: CatchPolicy = conf.catchPolicy, _ body: @escaping(Error) -> Void) -> PMKFinalizer {\n        let finalizer = PMKFinalizer()\n        pipe {\n            switch $0 {\n            case .rejected(let error):\n                guard policy == .allErrors || !error.isCancelled else {\n                    fallthrough\n                }\n                on.async(flags: flags) {\n                    body(error)\n                    finalizer.pending.resolve(())\n                }\n            case .fulfilled:\n                finalizer.pending.resolve(())\n            }\n        }\n        return finalizer\n    }\n}\n\npublic class PMKFinalizer {\n    let pending = Guarantee<Void>.pending()\n\n    /// `finally` is the same as `ensure`, but it is not chainable\n    public func finally(on: DispatchQueue? = conf.Q.return, flags: DispatchWorkItemFlags? = nil, _ body: @escaping () -> Void) {\n        pending.guarantee.done(on: on, flags: flags) {\n            body()\n        }\n    }\n}\n\n\npublic extension CatchMixin {\n    \n    /**\n     The provided closure executes when this promise rejects.\n     \n     Unlike `catch`, `recover` continues the chain.\n     Use `recover` in circumstances where recovering the chain from certain errors is a possibility. For example:\n\n         firstly {\n             CLLocationManager.requestLocation()\n         }.recover { error in\n             guard error == CLError.unknownLocation else { throw error }\n             return .value(CLLocation.chicago)\n         }\n     \n     - Parameter on: The queue to which the provided closure dispatches.\n     - Parameter body: The handler to execute if this promise is rejected.\n     - SeeAlso: [Cancellation](https://github.com/mxcl/PromiseKit/blob/master/Documentation/CommonPatterns.md#cancellation)\n     */\n    func recover<U: Thenable>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, policy: CatchPolicy = conf.catchPolicy, _ body: @escaping(Error) throws -> U) -> Promise<T> where U.T == T {\n        let rp = Promise<U.T>(.pending)\n        pipe {\n            switch $0 {\n            case .fulfilled(let value):\n                rp.box.seal(.fulfilled(value))\n            case .rejected(let error):\n                if policy == .allErrors || !error.isCancelled {\n                    on.async(flags: flags) {\n                        do {\n                            let rv = try body(error)\n                            guard rv !== rp else { throw PMKError.returnedSelf }\n                            rv.pipe(to: rp.box.seal)\n                        } catch {\n                            rp.box.seal(.rejected(error))\n                        }\n                    }\n                } else {\n                    rp.box.seal(.rejected(error))\n                }\n            }\n        }\n        return rp\n    }\n\n    /**\n     The provided closure executes when this promise rejects.\n     This variant of `recover` requires the handler to return a Guarantee, thus it returns a Guarantee itself and your closure cannot `throw`.\n     - Note it is logically impossible for this to take a `catchPolicy`, thus `allErrors` are handled.\n     - Parameter on: The queue to which the provided closure dispatches.\n     - Parameter body: The handler to execute if this promise is rejected.\n     - SeeAlso: [Cancellation](https://github.com/mxcl/PromiseKit/blob/master/Documentation/CommonPatterns.md#cancellation)\n     */\n    @discardableResult\n    func recover(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(Error) -> Guarantee<T>) -> Guarantee<T> {\n        let rg = Guarantee<T>(.pending)\n        pipe {\n            switch $0 {\n            case .fulfilled(let value):\n                rg.box.seal(value)\n            case .rejected(let error):\n                on.async(flags: flags) {\n                    body(error).pipe(to: rg.box.seal)\n                }\n            }\n        }\n        return rg\n    }\n\n    /**\n     The provided closure executes when this promise resolves, whether it rejects or not.\n     \n         firstly {\n             UIApplication.shared.networkActivityIndicatorVisible = true\n         }.done {\n             //…\n         }.ensure {\n             UIApplication.shared.networkActivityIndicatorVisible = false\n         }.catch {\n             //…\n         }\n     \n     - Parameter on: The queue to which the provided closure dispatches.\n     - Parameter body: The closure that executes when this promise resolves.\n     - Returns: A new promise, resolved with this promise’s resolution.\n     */\n    func ensure(on: DispatchQueue? = conf.Q.return, flags: DispatchWorkItemFlags? = nil, _ body: @escaping () -> Void) -> Promise<T> {\n        let rp = Promise<T>(.pending)\n        pipe { result in\n            on.async(flags: flags) {\n                body()\n                rp.box.seal(result)\n            }\n        }\n        return rp\n    }\n\n    /**\n     The provided closure executes when this promise resolves, whether it rejects or not.\n     The chain waits on the returned `Guarantee<Void>`.\n\n         firstly {\n             setup()\n         }.done {\n             //…\n         }.ensureThen {\n             teardown()  // -> Guarante<Void>\n         }.catch {\n             //…\n         }\n\n     - Parameter on: The queue to which the provided closure dispatches.\n     - Parameter body: The closure that executes when this promise resolves.\n     - Returns: A new promise, resolved with this promise’s resolution.\n     */\n    func ensureThen(on: DispatchQueue? = conf.Q.return, flags: DispatchWorkItemFlags? = nil, _ body: @escaping () -> Guarantee<Void>) -> Promise<T> {\n        let rp = Promise<T>(.pending)\n        pipe { result in\n            on.async(flags: flags) {\n                body().done {\n                    rp.box.seal(result)\n                }\n            }\n        }\n        return rp\n    }\n\n\n\n    /**\n     Consumes the Swift unused-result warning.\n     - Note: You should `catch`, but in situations where you know you don’t need a `catch`, `cauterize` makes your intentions clear.\n     */\n    @discardableResult\n    func cauterize() -> PMKFinalizer {\n        return self.catch {\n            conf.logHandler(.cauterized($0))\n        }\n    }\n}\n\n\npublic extension CatchMixin where T == Void {\n    \n    /**\n     The provided closure executes when this promise rejects.\n     \n     This variant of `recover` is specialized for `Void` promises and de-errors your chain returning a `Guarantee`, thus you cannot `throw` and you must handle all errors including cancellation.\n     \n     - Parameter on: The queue to which the provided closure dispatches.\n     - Parameter body: The handler to execute if this promise is rejected.\n     - SeeAlso: [Cancellation](https://github.com/mxcl/PromiseKit/blob/master/Documentation/CommonPatterns.md#cancellation)\n     */\n    @discardableResult\n    func recover(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(Error) -> Void) -> Guarantee<Void> {\n        let rg = Guarantee<Void>(.pending)\n        pipe {\n            switch $0 {\n            case .fulfilled:\n                rg.box.seal(())\n            case .rejected(let error):\n                on.async(flags: flags) {\n                    body(error)\n                    rg.box.seal(())\n                }\n            }\n        }\n        return rg\n    }\n\n    /**\n     The provided closure executes when this promise rejects.\n     \n     This variant of `recover` ensures that no error is thrown from the handler and allows specifying a catch policy.\n     \n     - Parameter on: The queue to which the provided closure dispatches.\n     - Parameter body: The handler to execute if this promise is rejected.\n     - SeeAlso: [Cancellation](https://github.com/mxcl/PromiseKit/blob/master/Documentation/CommonPatterns.md#cancellation)\n     */\n    func recover(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, policy: CatchPolicy = conf.catchPolicy, _ body: @escaping(Error) throws -> Void) -> Promise<Void> {\n        let rg = Promise<Void>(.pending)\n        pipe {\n            switch $0 {\n            case .fulfilled:\n                rg.box.seal(.fulfilled(()))\n            case .rejected(let error):\n                if policy == .allErrors || !error.isCancelled {\n                    on.async(flags: flags) {\n                        do {\n                            rg.box.seal(.fulfilled(try body(error)))\n                        } catch {\n                            rg.box.seal(.rejected(error))\n                        }\n                    }\n                } else {\n                    rg.box.seal(.rejected(error))\n                }\n            }\n        }\n        return rg\n    }\n}\n"
  },
  {
    "path": "Sources/Combine.swift",
    "content": "#if swift(>=4.1)\n#if canImport(Combine)\nimport Combine\n\n@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)\npublic extension Guarantee {\n    func future() -> Future<T, Never> {\n        .init { [weak self] promise in\n            self?.done { value in\n                promise(.success(value))\n            }\n        }\n    }\n}\n\n@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)\npublic extension Promise {\n    func future() -> Future<T, Error> {\n        .init { [weak self] promise in\n            self?.done { value in\n                promise(.success(value))\n            }.catch { error in\n                promise(.failure(error))\n            }\n        }\n    }\n}\n\n@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)\npublic extension Future {\n    func promise() -> PromiseKit.Promise<Output> {\n        return .init { [weak self] resolver in\n            var cancellable: AnyCancellable?\n            cancellable = self?.sink(receiveCompletion: { completion in\n                cancellable?.cancel()\n                cancellable = nil\n                switch completion {\n                case .failure(let error):\n                    resolver.reject(error)\n                case .finished:\n                    break\n                }\n            }, receiveValue: { value in\n                cancellable?.cancel()\n                cancellable = nil\n                resolver.fulfill(value)\n            })\n        }\n    }\n}\n\n@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)\npublic extension Future where Failure == Never {\n    func guarantee() -> Guarantee<Output> {\n        return .init { [weak self] resolver in\n            var cancellable: AnyCancellable?\n            cancellable = self?.sink(receiveValue: { value in\n                cancellable?.cancel()\n                cancellable = nil\n                resolver(value)\n            })\n        }\n    }\n}\n#endif\n#endif\n"
  },
  {
    "path": "Sources/Configuration.swift",
    "content": "import Dispatch\n\n/**\n PromiseKit’s configurable parameters.\n\n Do not change these after any Promise machinery executes as the configuration object is not thread-safe.\n\n We would like it to be, but sadly `Swift` does not expose `dispatch_once` et al. which is what we used to use in order to make the configuration immutable once first used.\n*/\npublic struct PMKConfiguration {\n    /// The default queues that promises handlers dispatch to\n    public var Q: (map: DispatchQueue?, return: DispatchQueue?) = (map: DispatchQueue.main, return: DispatchQueue.main)\n\n    /// The default catch-policy for all `catch` and `resolve`\n    public var catchPolicy = CatchPolicy.allErrorsExceptCancellation\n    \n    /// The closure used to log PromiseKit events.\n    /// Not thread safe; change before processing any promises.\n    /// - Note: The default handler calls `print()`\n    public var logHandler: (LogEvent) -> Void = { event in\n        switch event {\n        case .waitOnMainThread:\n            print(\"PromiseKit: warning: `wait()` called on main thread!\")\n        case .pendingPromiseDeallocated:\n            print(\"PromiseKit: warning: pending promise deallocated\")\n        case .pendingGuaranteeDeallocated:\n            print(\"PromiseKit: warning: pending guarantee deallocated\")\n        case .cauterized (let error):\n            print(\"PromiseKit:cauterized-error: \\(error)\")\n        }\n    }\n}\n\n/// Modify this as soon as possible in your application’s lifetime\npublic var conf = PMKConfiguration()\n"
  },
  {
    "path": "Sources/CustomStringConvertible.swift",
    "content": "\nextension Promise: CustomStringConvertible {\n    /// - Returns: A description of the state of this promise.\n    public var description: String {\n        switch result {\n        case nil:\n            return \"Promise(…\\(T.self))\"\n        case .rejected(let error)?:\n            return \"Promise(\\(error))\"\n        case .fulfilled(let value)?:\n            return \"Promise(\\(value))\"\n        }\n    }\n}\n\nextension Promise: CustomDebugStringConvertible {\n    /// - Returns: A debug-friendly description of the state of this promise.\n    public var debugDescription: String {\n        switch box.inspect() {\n        case .pending(let handlers):\n            return \"Promise<\\(T.self)>.pending(handlers: \\(handlers.bodies.count))\"\n        case .resolved(.rejected(let error)):\n            return \"Promise<\\(T.self)>.rejected(\\(type(of: error)).\\(error))\"\n        case .resolved(.fulfilled(let value)):\n            return \"Promise<\\(T.self)>.fulfilled(\\(value))\"\n        }\n    }\n}\n\n#if !SWIFT_PACKAGE\nextension AnyPromise {\n    /// - Returns: A description of the state of this promise.\n    override open var description: String {\n        switch box.inspect() {\n        case .pending:\n            return \"AnyPromise(…)\"\n        case .resolved(let obj?):\n            return \"AnyPromise(\\(obj))\"\n        case .resolved(nil):\n            return \"AnyPromise(nil)\"\n        }\n    }\n}\n#endif\n"
  },
  {
    "path": "Sources/Deprecations.swift",
    "content": "import Dispatch\n\n@available(*, deprecated, message: \"See `init(resolver:)`\")\npublic func wrap<T>(_ body: (@escaping (T?, Error?) -> Void) throws -> Void) -> Promise<T> {\n    return Promise { seal in\n        try body(seal.resolve)\n    }\n}\n\n@available(*, deprecated, message: \"See `init(resolver:)`\")\npublic func wrap<T>(_ body: (@escaping (T, Error?) -> Void) throws -> Void) -> Promise<T>  {\n    return Promise { seal in\n        try body(seal.resolve)\n    }\n}\n\n@available(*, deprecated, message: \"See `init(resolver:)`\")\npublic func wrap<T>(_ body: (@escaping (Error?, T?) -> Void) throws -> Void) -> Promise<T> {\n    return Promise { seal in\n        try body(seal.resolve)\n    }\n}\n\n@available(*, deprecated, message: \"See `init(resolver:)`\")\npublic func wrap(_ body: (@escaping (Error?) -> Void) throws -> Void) -> Promise<Void> {\n    return Promise { seal in\n        try body(seal.resolve)\n    }\n}\n\n@available(*, deprecated, message: \"See `init(resolver:)`\")\npublic func wrap<T>(_ body: (@escaping (T) -> Void) throws -> Void) -> Promise<T> {\n    return Promise { seal in\n        try body(seal.fulfill)\n    }\n}\n\npublic extension Promise {\n    @available(*, deprecated, message: \"See `ensure`\")\n    func always(on q: DispatchQueue = .main, execute body: @escaping () -> Void) -> Promise {\n        return ensure(on: q, body)\n    }\n}\n\npublic extension Thenable {\n#if PMKFullDeprecations\n    /// disabled due to ambiguity with the other `.flatMap`\n    @available(*, deprecated, message: \"See: `compactMap`\")\n    func flatMap<U>(on: DispatchQueue? = conf.Q.map, _ transform: @escaping(T) throws -> U?) -> Promise<U> {\n        return compactMap(on: on, transform)\n    }\n#endif\n}\n\npublic extension Thenable where T: Sequence {\n#if PMKFullDeprecations\n    /// disabled due to ambiguity with the other `.map`\n    @available(*, deprecated, message: \"See: `mapValues`\")\n    func map<U>(on: DispatchQueue? = conf.Q.map, _ transform: @escaping(T.Iterator.Element) throws -> U) -> Promise<[U]> {\n        return mapValues(on: on, transform)\n    }\n\n    /// disabled due to ambiguity with the other `.flatMap`\n    @available(*, deprecated, message: \"See: `flatMapValues`\")\n    func flatMap<U: Sequence>(on: DispatchQueue? = conf.Q.map, _ transform: @escaping(T.Iterator.Element) throws -> U) -> Promise<[U.Iterator.Element]> {\n        return flatMapValues(on: on, transform)\n    }\n#endif\n\n    @available(*, deprecated, message: \"See: `filterValues`\")\n    func filter(on: DispatchQueue? = conf.Q.map, test: @escaping (T.Iterator.Element) -> Bool) -> Promise<[T.Iterator.Element]> {\n        return filterValues(on: on, test)\n    }\n}\n\npublic extension Thenable where T: Collection {\n    @available(*, deprecated, message: \"See: `firstValue`\")\n    var first: Promise<T.Iterator.Element> {\n        return firstValue\n    }\n\n    @available(*, deprecated, message: \"See: `lastValue`\")\n    var last: Promise<T.Iterator.Element> {\n        return lastValue\n    }\n}\n\npublic extension Thenable where T: Sequence, T.Iterator.Element: Comparable {\n    @available(*, deprecated, message: \"See: `sortedValues`\")\n    func sorted(on: DispatchQueue? = conf.Q.map) -> Promise<[T.Iterator.Element]> {\n        return sortedValues(on: on)\n    }\n}\n"
  },
  {
    "path": "Sources/Error.swift",
    "content": "import Foundation\n\npublic enum PMKError: Error {\n    /**\n     The completionHandler with form `(T?, Error?)` was called with `(nil, nil)`.\n     This is invalid as per Cocoa/Apple calling conventions.\n     */\n    case invalidCallingConvention\n\n    /**\n     A handler returned its own promise. 99% of the time, this is likely a \n     programming error. It is also invalid per Promises/A+.\n     */\n    case returnedSelf\n\n    /** `when()`, `race()` etc. were called with invalid parameters, eg. an empty array. */\n    case badInput\n\n    /// The operation was cancelled\n    case cancelled\n\n    /// `nil` was returned from `flatMap`\n    @available(*, deprecated, message: \"See: `compactMap`\")\n    case flatMap(Any, Any.Type)\n\n    /// `nil` was returned from `compactMap`\n    case compactMap(Any, Any.Type)\n\n    /**\n     The lastValue or firstValue of a sequence was requested but the sequence was empty.\n\n     Also used if all values of this collection failed the test passed to `firstValue(where:)`.\n     */\n    case emptySequence\n\n    /// no winner in `race(fulfilled:)`\n    case noWinner\n}\n\nextension PMKError: CustomDebugStringConvertible {\n    public var debugDescription: String {\n        switch self {\n        case .flatMap(let obj, let type):\n            return \"Could not `flatMap<\\(type)>`: \\(obj)\"\n        case .compactMap(let obj, let type):\n            return \"Could not `compactMap<\\(type)>`: \\(obj)\"\n        case .invalidCallingConvention:\n            return \"A closure was called with an invalid calling convention, probably (nil, nil)\"\n        case .returnedSelf:\n            return \"A promise handler returned itself\"\n        case .badInput:\n            return \"Bad input was provided to a PromiseKit function\"\n        case .cancelled:\n            return \"The asynchronous sequence was cancelled\"\n        case .emptySequence:\n            return \"The first or last element was requested for an empty sequence\"\n        case .noWinner:\n            return \"All thenables passed to race(fulfilled:) were rejected\"\n        }\n    }\n}\n\nextension PMKError: LocalizedError {\n    public var errorDescription: String? {\n        return debugDescription\n    }\n}\n\n\n//////////////////////////////////////////////////////////// Cancellation\n\n/// An error that may represent the cancelled condition\npublic protocol CancellableError: Error {\n    /// returns true if this Error represents a cancelled condition\n    var isCancelled: Bool { get }\n}\n\nextension Error {\n    public var isCancelled: Bool {\n        do {\n            throw self\n        } catch PMKError.cancelled {\n            return true\n        } catch let error as CancellableError {\n            return error.isCancelled\n        } catch URLError.cancelled {\n            return true\n        } catch CocoaError.userCancelled {\n            return true\n        } catch let error as NSError {\n            #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)\n                let domain = error.domain\n                let code = error.code\n                return (\"SKErrorDomain\", 2) == (domain, code)\n            #else\n                return false\n            #endif\n        } catch {\n            return false\n        }\n    }\n}\n\n/// Used by `catch` and `recover`\npublic enum CatchPolicy {\n    /// Indicates that `catch` or `recover` handle all error types including cancellable-errors.\n    case allErrors\n\n    /// Indicates that `catch` or `recover` handle all error except cancellable-errors.\n    case allErrorsExceptCancellation\n}\n"
  },
  {
    "path": "Sources/Guarantee.swift",
    "content": "import class Foundation.Thread\nimport Dispatch\n\n/**\n A `Guarantee` is a functional abstraction around an asynchronous operation that cannot error.\n - See: `Thenable`\n*/\npublic final class Guarantee<T>: Thenable {\n    let box: PromiseKit.Box<T>\n\n    fileprivate init(box: SealedBox<T>) {\n        self.box = box\n    }\n\n    /// Returns a `Guarantee` sealed with the provided value.\n    public static func value(_ value: T) -> Guarantee<T> {\n        return .init(box: SealedBox(value: value))\n    }\n\n    /// Returns a pending `Guarantee` that can be resolved with the provided closure’s parameter.\n    public init(resolver body: (@escaping(T) -> Void) -> Void) {\n        box = Box()\n        body(box.seal)\n    }\n\n    /// - See: `Thenable.pipe`\n    public func pipe(to: @escaping(Result<T>) -> Void) {\n        pipe{ to(.fulfilled($0)) }\n    }\n\n    func pipe(to: @escaping(T) -> Void) {\n        switch box.inspect() {\n        case .pending:\n            box.inspect {\n                switch $0 {\n                case .pending(let handlers):\n                    handlers.append(to)\n                case .resolved(let value):\n                    to(value)\n                }\n            }\n        case .resolved(let value):\n            to(value)\n        }\n    }\n\n    /// - See: `Thenable.result`\n    public var result: Result<T>? {\n        switch box.inspect() {\n        case .pending:\n            return nil\n        case .resolved(let value):\n            return .fulfilled(value)\n        }\n    }\n\n    final private class Box<U>: EmptyBox<U> {\n        deinit {\n            switch inspect() {\n            case .pending:\n                PromiseKit.conf.logHandler(.pendingGuaranteeDeallocated)\n            case .resolved:\n                break\n            }\n        }\n    }\n\n    init(_: PMKUnambiguousInitializer) {\n        box = Box()\n    }\n\n    /// Returns a tuple of a pending `Guarantee` and a function that resolves it.\n    public class func pending() -> (guarantee: Guarantee<T>, resolve: (T) -> Void) {\n        return { ($0, $0.box.seal) }(Guarantee<T>(.pending))\n    }\n}\n\npublic extension Guarantee {\n    @discardableResult\n    func done(on: DispatchQueue? = conf.Q.return, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(T) -> Void) -> Guarantee<Void> {\n        let rg = Guarantee<Void>(.pending)\n        pipe { (value: T) in\n            on.async(flags: flags) {\n                body(value)\n                rg.box.seal(())\n            }\n        }\n        return rg\n    }\n    \n    func get(on: DispatchQueue? = conf.Q.return, flags: DispatchWorkItemFlags? = nil, _ body: @escaping (T) -> Void) -> Guarantee<T> {\n        return map(on: on, flags: flags) {\n            body($0)\n            return $0\n        }\n    }\n\n    func map<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(T) -> U) -> Guarantee<U> {\n        let rg = Guarantee<U>(.pending)\n        pipe { value in\n            on.async(flags: flags) {\n                rg.box.seal(body(value))\n            }\n        }\n        return rg\n    }\n\n    #if swift(>=4) && !swift(>=5.2)\n    func map<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ keyPath: KeyPath<T, U>) -> Guarantee<U> {\n        let rg = Guarantee<U>(.pending)\n        pipe { value in\n            on.async(flags: flags) {\n                rg.box.seal(value[keyPath: keyPath])\n            }\n        }\n        return rg\n    }\n    #endif\n\n    @discardableResult\n    func then<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(T) -> Guarantee<U>) -> Guarantee<U> {\n        let rg = Guarantee<U>(.pending)\n        pipe { value in\n            on.async(flags: flags) {\n                body(value).pipe(to: rg.box.seal)\n            }\n        }\n        return rg\n    }\n\n    func asVoid() -> Guarantee<Void> {\n        return map(on: nil) { _ in }\n    }\n    \n    /**\n     Blocks this thread, so you know, don’t call this on a serial thread that\n     any part of your chain may use. Like the main thread for example.\n     */\n    func wait() -> T {\n\n        if Thread.isMainThread {\n            conf.logHandler(.waitOnMainThread)\n        }\n\n        var result = value\n\n        if result == nil {\n            let group = DispatchGroup()\n            group.enter()\n            pipe { (foo: T) in result = foo; group.leave() }\n            group.wait()\n        }\n        \n        return result!\n    }\n}\n\npublic extension Guarantee where T: Sequence {\n    /**\n     `Guarantee<[T]>` => `T` -> `U` => `Guarantee<[U]>`\n\n         Guarantee.value([1,2,3])\n            .mapValues { integer in integer * 2 }\n            .done {\n                // $0 => [2,4,6]\n            }\n     */\n    func mapValues<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) -> U) -> Guarantee<[U]> {\n        return map(on: on, flags: flags) { $0.map(transform) }\n    }\n\n    #if swift(>=4) && !swift(>=5.2)\n    /**\n     `Guarantee<[T]>` => `KeyPath<T, U>` => `Guarantee<[U]>`\n\n         Guarantee.value([Person(name: \"Max\"), Person(name: \"Roman\"), Person(name: \"John\")])\n            .mapValues(\\.name)\n            .done {\n                // $0 => [\"Max\", \"Roman\", \"John\"]\n            }\n     */\n    func mapValues<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ keyPath: KeyPath<T.Iterator.Element, U>) -> Guarantee<[U]> {\n        return map(on: on, flags: flags) { $0.map { $0[keyPath: keyPath] } }\n    }\n    #endif\n\n    /**\n     `Guarantee<[T]>` => `T` -> `[U]` => `Guarantee<[U]>`\n\n         Guarantee.value([1,2,3])\n            .flatMapValues { integer in [integer, integer] }\n            .done {\n                // $0 => [1,1,2,2,3,3]\n            }\n     */\n    func flatMapValues<U: Sequence>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) -> U) -> Guarantee<[U.Iterator.Element]> {\n        return map(on: on, flags: flags) { (foo: T) in\n            foo.flatMap { transform($0) }\n        }\n    }\n\n    /**\n     `Guarantee<[T]>` => `T` -> `U?` => `Guarantee<[U]>`\n\n         Guarantee.value([\"1\",\"2\",\"a\",\"3\"])\n            .compactMapValues { Int($0) }\n            .done {\n                // $0 => [1,2,3]\n            }\n     */\n    func compactMapValues<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) -> U?) -> Guarantee<[U]> {\n        return map(on: on, flags: flags) { foo -> [U] in\n            #if !swift(>=3.3) || (swift(>=4) && !swift(>=4.1))\n            return foo.flatMap(transform)\n            #else\n            return foo.compactMap(transform)\n            #endif\n        }\n    }\n\n    #if swift(>=4) && !swift(>=5.2)\n    /**\n     `Guarantee<[T]>` => `KeyPath<T, U?>` => `Guarantee<[U]>`\n\n         Guarantee.value([Person(name: \"Max\"), Person(name: \"Roman\", age: 26), Person(name: \"John\", age: 23)])\n            .compactMapValues(\\.age)\n            .done {\n                // $0 => [26, 23]\n            }\n     */\n    func compactMapValues<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ keyPath: KeyPath<T.Iterator.Element, U?>) -> Guarantee<[U]> {\n        return map(on: on, flags: flags) { foo -> [U] in\n            #if !swift(>=4.1)\n            return foo.flatMap { $0[keyPath: keyPath] }\n            #else\n            return foo.compactMap { $0[keyPath: keyPath] }\n            #endif\n        }\n    }\n    #endif\n\n    /**\n     `Guarantee<[T]>` => `T` -> `Guarantee<U>` => `Guaranetee<[U]>`\n\n         Guarantee.value([1,2,3])\n            .thenMap { .value($0 * 2) }\n            .done {\n                // $0 => [2,4,6]\n            }\n     */\n    func thenMap<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) -> Guarantee<U>) -> Guarantee<[U]> {\n        return then(on: on, flags: flags) {\n            when(fulfilled: $0.map(transform))\n        }.recover {\n            // if happens then is bug inside PromiseKit\n            fatalError(String(describing: $0))\n        }\n    }\n\n    /**\n     `Guarantee<[T]>` => `T` -> `Guarantee<[U]>` => `Guarantee<[U]>`\n\n         Guarantee.value([1,2,3])\n            .thenFlatMap { integer in .value([integer, integer]) }\n            .done {\n                // $0 => [1,1,2,2,3,3]\n            }\n     */\n    func thenFlatMap<U: Thenable>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) -> U) -> Guarantee<[U.T.Iterator.Element]> where U.T: Sequence {\n        return then(on: on, flags: flags) {\n            when(fulfilled: $0.map(transform))\n        }.map(on: nil) {\n            $0.flatMap { $0 }\n        }.recover {\n            // if happens then is bug inside PromiseKit\n            fatalError(String(describing: $0))\n        }\n    }\n\n    /**\n     `Guarantee<[T]>` => `T` -> Bool => `Guarantee<[T]>`\n\n         Guarantee.value([1,2,3])\n            .filterValues { $0 > 1 }\n            .done {\n                // $0 => [2,3]\n            }\n     */\n    func filterValues(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ isIncluded: @escaping(T.Iterator.Element) -> Bool) -> Guarantee<[T.Iterator.Element]> {\n        return map(on: on, flags: flags) {\n            $0.filter(isIncluded)\n        }\n    }\n\n    #if swift(>=4) && !swift(>=5.2)\n    /**\n     `Guarantee<[T]>` => `KeyPath<T, Bool>` => `Guarantee<[T]>`\n\n         Guarantee.value([Person(name: \"Max\"), Person(name: \"Roman\", age: 26, isStudent: false), Person(name: \"John\", age: 23, isStudent: true)])\n            .filterValues(\\.isStudent)\n            .done {\n                // $0 => [Person(name: \"John\", age: 23, isStudent: true)]\n            }\n     */\n    func filterValues(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ keyPath: KeyPath<T.Iterator.Element, Bool>) -> Guarantee<[T.Iterator.Element]> {\n        return map(on: on, flags: flags) {\n            $0.filter { $0[keyPath: keyPath] }\n        }\n    }\n    #endif\n\n    /**\n     `Guarantee<[T]>` => (`T`, `T`) -> Bool => `Guarantee<[T]>`\n\n     Guarantee.value([5,2,3,4,1])\n        .sortedValues { $0 > $1 }\n        .done {\n            // $0 => [5,4,3,2,1]\n        }\n     */\n    func sortedValues(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ areInIncreasingOrder: @escaping(T.Iterator.Element, T.Iterator.Element) -> Bool) -> Guarantee<[T.Iterator.Element]> {\n        return map(on: on, flags: flags) {\n            $0.sorted(by: areInIncreasingOrder)\n        }\n    }\n}\n\npublic extension Guarantee where T: Sequence, T.Iterator.Element: Comparable {\n    /**\n     `Guarantee<[T]>` => `Guarantee<[T]>`\n\n     Guarantee.value([5,2,3,4,1])\n        .sortedValues()\n        .done {\n            // $0 => [1,2,3,4,5]\n        }\n     */\n    func sortedValues(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil) -> Guarantee<[T.Iterator.Element]> {\n        return map(on: on, flags: flags) { $0.sorted() }\n    }\n}\n\n#if swift(>=3.1)\npublic extension Guarantee where T == Void {\n    convenience init() {\n        self.init(box: SealedBox(value: Void()))\n    }\n\n    static var value: Guarantee<Void> {\n        return .value(Void())\n    }\n}\n#endif\n\n\npublic extension DispatchQueue {\n    /**\n     Asynchronously executes the provided closure on a dispatch queue.\n\n         DispatchQueue.global().async(.promise) {\n             md5(input)\n         }.done { md5 in\n             //…\n         }\n\n     - Parameter body: The closure that resolves this promise.\n     - Returns: A new `Guarantee` resolved by the result of the provided closure.\n     - Note: There is no Promise/Thenable version of this due to Swift compiler ambiguity issues.\n     */\n    @available(macOS 10.10, iOS 2.0, tvOS 10.0, watchOS 2.0, *)\n    final func async<T>(_: PMKNamespacer, group: DispatchGroup? = nil, qos: DispatchQoS = .default, flags: DispatchWorkItemFlags = [], execute body: @escaping () -> T) -> Guarantee<T> {\n        let rg = Guarantee<T>(.pending)\n        async(group: group, qos: qos, flags: flags) {\n            rg.box.seal(body())\n        }\n        return rg\n    }\n}\n\n\n#if os(Linux)\nimport func CoreFoundation._CFIsMainThread\n\nextension Thread {\n    // `isMainThread` is not implemented yet in swift-corelibs-foundation.\n    static var isMainThread: Bool {\n        return _CFIsMainThread()\n    }\n}\n#endif\n"
  },
  {
    "path": "Sources/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>$(CURRENT_PROJECT_VERSION)</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "Sources/LogEvent.swift",
    "content": "/**\n    The PromiseKit events which may be logged.\n \n    ````\n    /// A promise or guarantee has blocked the main thread\n    case waitOnMainThread\n \n    /// A promise has been deallocated without being resolved\n    case pendingPromiseDeallocated\n \n    /// An error which occurred while fulfilling a promise was swallowed\n    case cauterized(Error)\n \n    /// Errors which give a string error message\n    case misc (String)\n    ````\n*/\npublic enum LogEvent {\n    /// A promise or guarantee has blocked the main thread\n    case waitOnMainThread\n    \n    /// A promise has been deallocated without being resolved\n    case pendingPromiseDeallocated\n    \n    /// A guarantee has been deallocated without being resolved\n    case pendingGuaranteeDeallocated\n    \n    /// An error which occurred while resolving a promise was swallowed\n    case cauterized(Error)\n}\n"
  },
  {
    "path": "Sources/NSMethodSignatureForBlock.m",
    "content": "#import <Foundation/NSMethodSignature.h>\n\nstruct PMKBlockLiteral {\n    void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock\n    int flags;\n    int reserved;\n    void (*invoke)(void *, ...);\n    struct block_descriptor {\n        unsigned long int reserved;\t// NULL\n    \tunsigned long int size;         // sizeof(struct Block_literal_1)\n        // optional helper functions\n    \tvoid (*copy_helper)(void *dst, void *src);     // IFF (1<<25)\n    \tvoid (*dispose_helper)(void *src);             // IFF (1<<25)\n        // required ABI.2010.3.16\n        const char *signature;                         // IFF (1<<30)\n    } *descriptor;\n    // imported variables\n};\n\ntypedef NS_OPTIONS(NSUInteger, PMKBlockDescriptionFlags) {\n    PMKBlockDescriptionFlagsHasCopyDispose = (1 << 25),\n    PMKBlockDescriptionFlagsHasCtor = (1 << 26), // helpers have C++ code\n    PMKBlockDescriptionFlagsIsGlobal = (1 << 28),\n    PMKBlockDescriptionFlagsHasStret = (1 << 29), // IFF BLOCK_HAS_SIGNATURE\n    PMKBlockDescriptionFlagsHasSignature = (1 << 30)\n};\n\n// It appears 10.7 doesn't support quotes in method signatures. Remove them\n// via @rabovik's method. See https://github.com/OliverLetterer/SLObjectiveCRuntimeAdditions/pull/2\n#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8\nNS_INLINE static const char * pmk_removeQuotesFromMethodSignature(const char *str){\n    char *result = malloc(strlen(str) + 1);\n    BOOL skip = NO;\n    char *to = result;\n    char c;\n    while ((c = *str++)) {\n        if ('\"' == c) {\n            skip = !skip;\n            continue;\n        }\n        if (skip) continue;\n        *to++ = c;\n    }\n    *to = '\\0';\n    return result;\n}\n#endif\n\nstatic NSMethodSignature *NSMethodSignatureForBlock(id block) {\n    if (!block)\n        return nil;\n\n    struct PMKBlockLiteral *blockRef = (__bridge struct PMKBlockLiteral *)block;\n    PMKBlockDescriptionFlags flags = (PMKBlockDescriptionFlags)blockRef->flags;\n\n    if (flags & PMKBlockDescriptionFlagsHasSignature) {\n        void *signatureLocation = blockRef->descriptor;\n        signatureLocation += sizeof(unsigned long int);\n        signatureLocation += sizeof(unsigned long int);\n\n        if (flags & PMKBlockDescriptionFlagsHasCopyDispose) {\n            signatureLocation += sizeof(void(*)(void *dst, void *src));\n            signatureLocation += sizeof(void (*)(void *src));\n        }\n\n        const char *signature = (*(const char **)signatureLocation);\n#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8\n        signature = pmk_removeQuotesFromMethodSignature(signature);\n        NSMethodSignature *nsSignature = [NSMethodSignature signatureWithObjCTypes:signature];\n        free((void *)signature);\n\n        return nsSignature;\n#endif\n        return [NSMethodSignature signatureWithObjCTypes:signature];\n    }\n    return 0;\n}\n"
  },
  {
    "path": "Sources/PMKCallVariadicBlock.m",
    "content": "#import \"NSMethodSignatureForBlock.m\"\n#import <Foundation/NSDictionary.h>\n#import <Foundation/NSException.h>\n#import \"AnyPromise+Private.h\"\n#import <Foundation/NSError.h>\n#import <dispatch/once.h>\n#import <string.h>\n\n#ifndef PMKLog\n#define PMKLog NSLog\n#endif\n\n@interface PMKArray : NSObject {\n@public\n    id objs[3];\n    NSUInteger count;\n} @end\n\n@implementation PMKArray\n\n- (id)objectAtIndexedSubscript:(NSUInteger)idx {\n    if (count <= idx) {\n        // this check is necessary due to lack of checks in `pmk_safely_call_block`\n        return nil;\n    }\n    return objs[idx];\n}\n\n@end\n\nid __PMKArrayWithCount(NSUInteger count, ...) {\n    PMKArray *this = [PMKArray new];\n    this->count = count;\n    va_list args;\n    va_start(args, count);\n    for (NSUInteger x = 0; x < count; ++x)\n        this->objs[x] = va_arg(args, id);\n    va_end(args);\n    return this;\n}\n\n\nstatic inline id _PMKCallVariadicBlock(id frock, id result) {\n    NSCAssert(frock, @\"\");\n\n    NSMethodSignature *sig = NSMethodSignatureForBlock(frock);\n    const NSUInteger nargs = sig.numberOfArguments;\n    const char rtype = sig.methodReturnType[0];\n\n    #define call_block_with_rtype(type) ({^type{ \\\n        switch (nargs) { \\\n            case 1: \\\n                return ((type(^)(void))frock)(); \\\n            case 2: { \\\n                const id arg = [result class] == [PMKArray class] ? result[0] : result; \\\n                return ((type(^)(id))frock)(arg); \\\n            } \\\n            case 3: { \\\n                type (^block)(id, id) = frock; \\\n                return [result class] == [PMKArray class] \\\n                    ? block(result[0], result[1]) \\\n                    : block(result, nil); \\\n            } \\\n            case 4: { \\\n                type (^block)(id, id, id) = frock; \\\n                return [result class] == [PMKArray class] \\\n                    ? block(result[0], result[1], result[2]) \\\n                    : block(result, nil, nil); \\\n            } \\\n            default: \\\n                @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@\"PromiseKit: The provided block’s argument count is unsupported.\" userInfo:nil]; \\\n        }}();})\n\n    switch (rtype) {\n        case 'v':\n            call_block_with_rtype(void);\n            return nil;\n        case '@':\n            return call_block_with_rtype(id) ?: nil;\n        case '*': {\n            char *str = call_block_with_rtype(char *);\n            return str ? @(str) : nil;\n        }\n        case 'c': return @(call_block_with_rtype(char));\n        case 'i': return @(call_block_with_rtype(int));\n        case 's': return @(call_block_with_rtype(short));\n        case 'l': return @(call_block_with_rtype(long));\n        case 'q': return @(call_block_with_rtype(long long));\n        case 'C': return @(call_block_with_rtype(unsigned char));\n        case 'I': return @(call_block_with_rtype(unsigned int));\n        case 'S': return @(call_block_with_rtype(unsigned short));\n        case 'L': return @(call_block_with_rtype(unsigned long));\n        case 'Q': return @(call_block_with_rtype(unsigned long long));\n        case 'f': return @(call_block_with_rtype(float));\n        case 'd': return @(call_block_with_rtype(double));\n        case 'B': return @(call_block_with_rtype(_Bool));\n        case '^':\n            if (strcmp(sig.methodReturnType, \"^v\") == 0) {\n                call_block_with_rtype(void);\n                return nil;\n            }\n            // else fall through!\n        default:\n            @throw [NSException exceptionWithName:@\"PromiseKit\" reason:@\"PromiseKit: Unsupported method signature.\" userInfo:nil];\n    }\n}\n\nstatic id PMKCallVariadicBlock(id frock, id result) {\n    @try {\n        return _PMKCallVariadicBlock(frock, result);\n    } @catch (id thrown) {\n        if ([thrown isKindOfClass:[NSString class]])\n            return thrown;\n        if ([thrown isKindOfClass:[NSError class]])\n            return thrown;\n\n        // we don’t catch objc exceptions: they are meant to crash your app\n        @throw thrown;\n    }\n}\n"
  },
  {
    "path": "Sources/Promise.swift",
    "content": "import class Foundation.Thread\nimport Dispatch\n\n/**\n A `Promise` is a functional abstraction around a failable asynchronous operation.\n - See: `Thenable`\n */\npublic final class Promise<T>: Thenable, CatchMixin {\n    let box: Box<Result<T>>\n\n    fileprivate init(box: SealedBox<Result<T>>) {\n        self.box = box\n    }\n\n    /**\n      Initialize a new fulfilled promise.\n\n      We do not provide `init(value:)` because Swift is “greedy”\n      and would pick that initializer in cases where it should pick\n      one of the other more specific options leading to Promises with\n      `T` that is eg: `Error` or worse `(T->Void,Error->Void)` for\n      uses of our PMK < 4 pending initializer due to Swift trailing\n      closure syntax (nothing good comes without pain!).\n\n      Though often easy to detect, sometimes these issues would be\n      hidden by other type inference leading to some nasty bugs in\n      production.\n\n      In PMK5 we tried to work around this by making the pending\n      initializer take the form `Promise(.pending)` but this led to\n      bad migration errors for PMK4 users. Hence instead we quickly\n      released PMK6 and now only provide this initializer for making\n      sealed & fulfilled promises.\n\n      Usage is still (usually) good:\n\n          guard foo else {\n              return .value(bar)\n          }\n     */\n    public static func value(_ value: T) -> Promise<T> {\n        return Promise(box: SealedBox(value: .fulfilled(value)))\n    }\n\n    /// Initialize a new rejected promise.\n    public init(error: Error) {\n        box = SealedBox(value: .rejected(error))\n    }\n\n    /// Initialize a new promise bound to the provided `Thenable`.\n    public init<U: Thenable>(_ bridge: U) where U.T == T {\n        box = EmptyBox()\n        bridge.pipe(to: box.seal)\n    }\n\n    /// Initialize a new promise that can be resolved with the provided `Resolver`.\n    public init(resolver body: (Resolver<T>) throws -> Void) {\n        box = EmptyBox()\n        let resolver = Resolver(box)\n        do {\n            try body(resolver)\n        } catch {\n            resolver.reject(error)\n        }\n    }\n\n    /// - Returns: a tuple of a new pending promise and its `Resolver`.\n    public class func pending() -> (promise: Promise<T>, resolver: Resolver<T>) {\n        return { ($0, Resolver($0.box)) }(Promise<T>(.pending))\n    }\n\n    /// - See: `Thenable.pipe`\n    public func pipe(to: @escaping(Result<T>) -> Void) {\n        switch box.inspect() {\n        case .pending:\n            box.inspect {\n                switch $0 {\n                case .pending(let handlers):\n                    handlers.append(to)\n                case .resolved(let value):\n                    to(value)\n                }\n            }\n        case .resolved(let value):\n            to(value)\n        }\n    }\n\n    /// - See: `Thenable.result`\n    public var result: Result<T>? {\n        switch box.inspect() {\n        case .pending:\n            return nil\n        case .resolved(let result):\n            return result\n        }\n    }\n\n    init(_: PMKUnambiguousInitializer) {\n        box = EmptyBox()\n    }\n}\n\npublic extension Promise {\n    /**\n     Blocks this thread, so—you know—don’t call this on a serial thread that\n     any part of your chain may use. Like the main thread for example.\n     */\n    func wait() throws -> T {\n\n        if Thread.isMainThread {\n            conf.logHandler(LogEvent.waitOnMainThread)\n        }\n\n        var result = self.result\n\n        if result == nil {\n            let group = DispatchGroup()\n            group.enter()\n            pipe { result = $0; group.leave() }\n            group.wait()\n        }\n\n        switch result! {\n        case .rejected(let error):\n            throw error\n        case .fulfilled(let value):\n            return value\n        }\n    }\n}\n\n#if swift(>=3.1)\nextension Promise where T == Void {\n    /// Initializes a new promise fulfilled with `Void`\n    public convenience init() {\n        self.init(box: SealedBox(value: .fulfilled(Void())))\n    }\n\n    /// Returns a new promise fulfilled with `Void`\n    public static var value: Promise<Void> {\n        return .value(Void())\n    }\n}\n#endif\n\n\npublic extension DispatchQueue {\n    /**\n     Asynchronously executes the provided closure on a dispatch queue.\n\n         DispatchQueue.global().async(.promise) {\n             try md5(input)\n         }.done { md5 in\n             //…\n         }\n\n     - Parameter body: The closure that resolves this promise.\n     - Returns: A new `Promise` resolved by the result of the provided closure.\n     - Note: There is no Promise/Thenable version of this due to Swift compiler ambiguity issues.\n     */\n    @available(macOS 10.10, iOS 8.0, tvOS 9.0, watchOS 2.0, *)\n    final func async<T>(_: PMKNamespacer, group: DispatchGroup? = nil, qos: DispatchQoS = .default, flags: DispatchWorkItemFlags = [], execute body: @escaping () throws -> T) -> Promise<T> {\n        let promise = Promise<T>(.pending)\n        async(group: group, qos: qos, flags: flags) {\n            do {\n                promise.box.seal(.fulfilled(try body()))\n            } catch {\n                promise.box.seal(.rejected(error))\n            }\n        }\n        return promise\n    }\n}\n\n\n/// used by our extensions to provide unambiguous functions with the same name as the original function\npublic enum PMKNamespacer {\n    case promise\n}\n\nenum PMKUnambiguousInitializer {\n    case pending\n}\n"
  },
  {
    "path": "Sources/PromiseKit.h",
    "content": "#import <PromiseKit/fwd.h>\n#import <PromiseKit/AnyPromise.h>\n\n#import <Foundation/NSObjCRuntime.h>  // `FOUNDATION_EXPORT`\n\nFOUNDATION_EXPORT double PromiseKitVersionNumber;\nFOUNDATION_EXPORT const unsigned char PromiseKitVersionString[];\n"
  },
  {
    "path": "Sources/Resolver.swift",
    "content": "/// An object for resolving promises\npublic final class Resolver<T> {\n    let box: Box<Result<T>>\n\n    init(_ box: Box<Result<T>>) {\n        self.box = box\n    }\n\n    deinit {\n        if case .pending = box.inspect() {\n            conf.logHandler(.pendingPromiseDeallocated)\n        }\n    }\n}\n\npublic extension Resolver {\n    /// Fulfills the promise with the provided value\n    func fulfill(_ value: T) {\n        box.seal(.fulfilled(value))\n    }\n\n    /// Rejects the promise with the provided error\n    func reject(_ error: Error) {\n        box.seal(.rejected(error))\n    }\n\n    /// Resolves the promise with the provided result\n    func resolve(_ result: Result<T>) {\n        box.seal(result)\n    }\n\n    /// Resolves the promise with the provided value or error\n    func resolve(_ obj: T?, _ error: Error?) {\n        if let error = error {\n            reject(error)\n        } else if let obj = obj {\n            fulfill(obj)\n        } else {\n            reject(PMKError.invalidCallingConvention)\n        }\n    }\n\n    /// Fulfills the promise with the provided value unless the provided error is non-nil\n    func resolve(_ obj: T, _ error: Error?) {\n        if let error = error {\n            reject(error)\n        } else {\n            fulfill(obj)\n        }\n    }\n\n    /// Resolves the promise, provided for non-conventional value-error ordered completion handlers.\n    func resolve(_ error: Error?, _ obj: T?) {\n        resolve(obj, error)\n    }\n}\n\n#if swift(>=3.1)\nextension Resolver where T == Void {\n    /// Fulfills the promise unless error is non-nil\n    public func resolve(_ error: Error?) {\n        if let error = error {\n            reject(error)\n        } else {\n            fulfill(())\n        }\n    }\n#if false\n    // disabled ∵ https://github.com/mxcl/PromiseKit/issues/990\n\n    /// Fulfills the promise\n    public func fulfill() {\n        self.fulfill(())\n    }\n#else\n    /// Fulfills the promise\n    /// - Note: underscore is present due to: https://github.com/mxcl/PromiseKit/issues/990\n    public func fulfill_() {\n        self.fulfill(())\n    }\n#endif\n}\n#endif\n\n#if swift(>=5.0)\nextension Resolver {\n    /// Resolves the promise with the provided result\n    public func resolve<E: Error>(_ result: Swift.Result<T, E>) {\n        switch result {\n        case .failure(let error): self.reject(error)\n        case .success(let value): self.fulfill(value)\n        }\n    }\n}\n#endif\n\npublic enum Result<T> {\n    case fulfilled(T)\n    case rejected(Error)\n}\n\npublic extension PromiseKit.Result {\n    var isFulfilled: Bool {\n        switch self {\n        case .fulfilled:\n            return true\n        case .rejected:\n            return false\n        }\n    }\n}\n"
  },
  {
    "path": "Sources/Resources/PrivacyInfo.xcprivacy",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>NSPrivacyTracking</key>\n\t<false/>\n\t<key>NSPrivacyCollectedDataTypes</key>\n\t<array/>\n</dict>\n</plist>\n"
  },
  {
    "path": "Sources/Thenable.swift",
    "content": "import Dispatch\n\n/// Thenable represents an asynchronous operation that can be chained.\npublic protocol Thenable: AnyObject {\n    /// The type of the wrapped value\n    associatedtype T\n\n    /// `pipe` is immediately executed when this `Thenable` is resolved\n    func pipe(to: @escaping(Result<T>) -> Void)\n\n    /// The resolved result or nil if pending.\n    var result: Result<T>? { get }\n}\n\npublic extension Thenable {\n    /**\n     The provided closure executes when this promise is fulfilled.\n     \n     This allows chaining promises. The promise returned by the provided closure is resolved before the promise returned by this closure resolves.\n     \n     - Parameter on: The queue to which the provided closure dispatches.\n     - Parameter body: The closure that executes when this promise is fulfilled. It must return a promise.\n     - Returns: A new promise that resolves when the promise returned from the provided closure resolves. For example:\n\n           firstly {\n               URLSession.shared.dataTask(.promise, with: url1)\n           }.then { response in\n               transform(data: response.data)\n           }.done { transformation in\n               //…\n           }\n     */\n    func then<U: Thenable>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(T) throws -> U) -> Promise<U.T> {\n        let rp = Promise<U.T>(.pending)\n        pipe {\n            switch $0 {\n            case .fulfilled(let value):\n                on.async(flags: flags) {\n                    do {\n                        let rv = try body(value)\n                        guard rv !== rp else { throw PMKError.returnedSelf }\n                        rv.pipe(to: rp.box.seal)\n                    } catch {\n                        rp.box.seal(.rejected(error))\n                    }\n                }\n            case .rejected(let error):\n                rp.box.seal(.rejected(error))\n            }\n        }\n        return rp\n    }\n\n    /**\n     The provided closure is executed when this promise is fulfilled.\n     \n     This is like `then` but it requires the closure to return a non-promise.\n     \n     - Parameter on: The queue to which the provided closure dispatches.\n     - Parameter transform: The closure that is executed when this Promise is fulfilled. It must return a non-promise.\n     - Returns: A new promise that is fulfilled with the value returned from the provided closure or rejected if the provided closure throws. For example:\n\n           firstly {\n               URLSession.shared.dataTask(.promise, with: url1)\n           }.map { response in\n               response.data.length\n           }.done { length in\n               //…\n           }\n     */\n    func map<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T) throws -> U) -> Promise<U> {\n        let rp = Promise<U>(.pending)\n        pipe {\n            switch $0 {\n            case .fulfilled(let value):\n                on.async(flags: flags) {\n                    do {\n                        rp.box.seal(.fulfilled(try transform(value)))\n                    } catch {\n                        rp.box.seal(.rejected(error))\n                    }\n                }\n            case .rejected(let error):\n                rp.box.seal(.rejected(error))\n            }\n        }\n        return rp\n    }\n\n    #if swift(>=4) && !swift(>=5.2)\n    /**\n     Similar to func `map<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T) throws -> U) -> Promise<U>`, but accepts a key path instead of a closure.\n     \n     - Parameter on: The queue to which the provided key path for value dispatches.\n     - Parameter keyPath: The key path to the value that is using when this Promise is fulfilled.\n     - Returns: A new promise that is fulfilled with the value for the provided key path.\n     */\n    func map<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ keyPath: KeyPath<T, U>) -> Promise<U> {\n        let rp = Promise<U>(.pending)\n        pipe {\n            switch $0 {\n            case .fulfilled(let value):\n                on.async(flags: flags) {\n                    rp.box.seal(.fulfilled(value[keyPath: keyPath]))\n                }\n            case .rejected(let error):\n                rp.box.seal(.rejected(error))\n            }\n        }\n        return rp\n    }\n    #endif\n\n    /**\n      The provided closure is executed when this promise is fulfilled.\n\n      In your closure return an `Optional`, if you return `nil` the resulting promise is rejected with `PMKError.compactMap`, otherwise the promise is fulfilled with the unwrapped value.\n\n           firstly {\n               URLSession.shared.dataTask(.promise, with: url)\n           }.compactMap {\n               try JSONSerialization.jsonObject(with: $0.data) as? [String: String]\n           }.done { dictionary in\n               //…\n           }.catch {\n               // either `PMKError.compactMap` or a `JSONError`\n           }\n     */\n    func compactMap<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T) throws -> U?) -> Promise<U> {\n        let rp = Promise<U>(.pending)\n        pipe {\n            switch $0 {\n            case .fulfilled(let value):\n                on.async(flags: flags) {\n                    do {\n                        if let rv = try transform(value) {\n                            rp.box.seal(.fulfilled(rv))\n                        } else {\n                            throw PMKError.compactMap(value, U.self)\n                        }\n                    } catch {\n                        rp.box.seal(.rejected(error))\n                    }\n                }\n            case .rejected(let error):\n                rp.box.seal(.rejected(error))\n            }\n        }\n        return rp\n    }\n\n    #if swift(>=4) && !swift(>=5.2)\n    /**\n    Similar to func `compactMap<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T) throws -> U?) -> Promise<U>`, but accepts a key path instead of a closure.\n    \n    - Parameter on: The queue to which the provided key path for value dispatches.\n    - Parameter keyPath: The key path to the value that is using when this Promise is fulfilled. If the value for `keyPath` is `nil` the resulting promise is rejected with `PMKError.compactMap`.\n    - Returns: A new promise that is fulfilled with the value for the provided key path.\n    */\n    func compactMap<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ keyPath: KeyPath<T, U?>) -> Promise<U> {\n        let rp = Promise<U>(.pending)\n        pipe {\n            switch $0 {\n            case .fulfilled(let value):\n                on.async(flags: flags) {\n                    do {\n                        if let rv = value[keyPath: keyPath] {\n                            rp.box.seal(.fulfilled(rv))\n                        } else {\n                            throw PMKError.compactMap(value, U.self)\n                        }\n                    } catch {\n                        rp.box.seal(.rejected(error))\n                    }\n                }\n            case .rejected(let error):\n                rp.box.seal(.rejected(error))\n            }\n        }\n        return rp\n    }\n    #endif\n\n    /**\n     The provided closure is executed when this promise is fulfilled.\n     \n     Equivalent to `map { x -> Void in`, but since we force the `Void` return Swift\n     is happier and gives you less hassle about your closure’s qualification.\n     \n     - Parameter on: The queue to which the provided closure dispatches.\n     - Parameter body: The closure that is executed when this Promise is fulfilled.\n     - Returns: A new promise fulfilled as `Void` or rejected if the provided closure throws.\n     \n           firstly {\n               URLSession.shared.dataTask(.promise, with: url)\n           }.done { response in\n               print(response.data)\n           }\n     */\n    func done(on: DispatchQueue? = conf.Q.return, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(T) throws -> Void) -> Promise<Void> {\n        let rp = Promise<Void>(.pending)\n        pipe {\n            switch $0 {\n            case .fulfilled(let value):\n                on.async(flags: flags) {\n                    do {\n                        try body(value)\n                        rp.box.seal(.fulfilled(()))\n                    } catch {\n                        rp.box.seal(.rejected(error))\n                    }\n                }\n            case .rejected(let error):\n                rp.box.seal(.rejected(error))\n            }\n        }\n        return rp\n    }\n\n    /**\n     The provided closure is executed when this promise is fulfilled.\n     \n     This is like `done` but it returns the same value that the handler is fed.\n     `get` immutably accesses the fulfilled value; the returned Promise maintains that value.\n     \n     - Parameter on: The queue to which the provided closure dispatches.\n     - Parameter body: The closure that is executed when this Promise is fulfilled.\n     - Returns: A new promise that is fulfilled with the value that the handler is fed or rejected if the provided closure throws. For example:\n     \n           firstly {\n               .value(1)\n           }.get { foo in\n               print(foo, \" is 1\")\n           }.done { foo in\n               print(foo, \" is 1\")\n           }.done { foo in\n               print(foo, \" is Void\")\n           }\n     */\n    func get(on: DispatchQueue? = conf.Q.return, flags: DispatchWorkItemFlags? = nil, _ body: @escaping (T) throws -> Void) -> Promise<T> {\n        return map(on: on, flags: flags) {\n            try body($0)\n            return $0\n        }\n    }\n\n    /**\n     The provided closure is executed with promise result.\n\n     This is like `get` but provides the Result<T> of the Promise so you can inspect the value of the chain at this point without causing any side effects.\n\n     - Parameter on: The queue to which the provided closure dispatches.\n     - Parameter body: The closure that is executed with Result of Promise.\n     - Returns: A new promise that is resolved with the result that the handler is fed. For example:\n\n     promise.tap{ print($0) }.then{ /*…*/ }\n     */\n    func tap(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(Result<T>) -> Void) -> Promise<T> {\n        return Promise { seal in\n            pipe { result in\n                on.async(flags: flags) {\n                    body(result)\n                    seal.resolve(result)\n                }\n            }\n        }\n    }\n\n    /// - Returns: a new promise chained off this promise but with its value discarded.\n    func asVoid() -> Promise<Void> {\n        return map(on: nil) { _ in }\n    }\n}\n\npublic extension Thenable {\n    /**\n     - Returns: The error with which this promise was rejected; `nil` if this promise is not rejected.\n     */\n    var error: Error? {\n        switch result {\n        case .none:\n            return nil\n        case .some(.fulfilled):\n            return nil\n        case .some(.rejected(let error)):\n            return error\n        }\n    }\n\n    /**\n     - Returns: `true` if the promise has not yet resolved.\n     */\n    var isPending: Bool {\n        return result == nil\n    }\n\n    /**\n     - Returns: `true` if the promise has resolved.\n     */\n    var isResolved: Bool {\n        return !isPending\n    }\n\n    /**\n     - Returns: `true` if the promise was fulfilled.\n     */\n    var isFulfilled: Bool {\n        return value != nil\n    }\n\n    /**\n     - Returns: `true` if the promise was rejected.\n     */\n    var isRejected: Bool {\n        return error != nil\n    }\n\n    /**\n     - Returns: The value with which this promise was fulfilled or `nil` if this promise is pending or rejected.\n     */\n    var value: T? {\n        switch result {\n        case .none:\n            return nil\n        case .some(.fulfilled(let value)):\n            return value\n        case .some(.rejected):\n            return nil\n        }\n    }\n}\n\npublic extension Thenable where T: Sequence {\n    /**\n     `Promise<[T]>` => `T` -> `U` => `Promise<[U]>`\n\n         firstly {\n             .value([1,2,3])\n         }.mapValues { integer in\n             integer * 2\n         }.done {\n             // $0 => [2,4,6]\n         }\n     */\n    func mapValues<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) throws -> U) -> Promise<[U]> {\n        return map(on: on, flags: flags){ try $0.map(transform) }\n    }\n\n    #if swift(>=4) && !swift(>=5.2)\n    /**\n     `Promise<[T]>` => `KeyPath<T, U>` => `Promise<[U]>`\n\n         firstly {\n             .value([Person(name: \"Max\"), Person(name: \"Roman\"), Person(name: \"John\")])\n         }.mapValues(\\.name).done {\n             // $0 => [\"Max\", \"Roman\", \"John\"]\n         }\n     */\n    func mapValues<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ keyPath: KeyPath<T.Iterator.Element, U>) -> Promise<[U]> {\n        return map(on: on, flags: flags){ $0.map { $0[keyPath: keyPath] } }\n    }\n    #endif\n\n    /**\n     `Promise<[T]>` => `T` -> `[U]` => `Promise<[U]>`\n\n         firstly {\n             .value([1,2,3])\n         }.flatMapValues { integer in\n             [integer, integer]\n         }.done {\n             // $0 => [1,1,2,2,3,3]\n         }\n     */\n    func flatMapValues<U: Sequence>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) throws -> U) -> Promise<[U.Iterator.Element]> {\n        return map(on: on, flags: flags){ (foo: T) in\n            try foo.flatMap{ try transform($0) }\n        }\n    }\n\n    /**\n     `Promise<[T]>` => `T` -> `U?` => `Promise<[U]>`\n\n         firstly {\n             .value([\"1\",\"2\",\"a\",\"3\"])\n         }.compactMapValues {\n             Int($0)\n         }.done {\n             // $0 => [1,2,3]\n         }\n     */\n    func compactMapValues<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) throws -> U?) -> Promise<[U]> {\n        return map(on: on, flags: flags) { foo -> [U] in\n          #if !swift(>=3.3) || (swift(>=4) && !swift(>=4.1))\n            return try foo.flatMap(transform)\n          #else\n            return try foo.compactMap(transform)\n          #endif\n        }\n    }\n\n    #if swift(>=4) && !swift(>=5.2)\n    /**\n     `Promise<[T]>` => `KeyPath<T, U?>` => `Promise<[U]>`\n\n         firstly {\n             .value([Person(name: \"Max\"), Person(name: \"Roman\", age: 26), Person(name: \"John\", age: 23)])\n         }.compactMapValues(\\.age).done {\n             // $0 => [26, 23]\n         }\n     */\n    func compactMapValues<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ keyPath: KeyPath<T.Iterator.Element, U?>) -> Promise<[U]> {\n        return map(on: on, flags: flags) { foo -> [U] in\n          #if !swift(>=4.1)\n            return foo.flatMap { $0[keyPath: keyPath] }\n          #else\n            return foo.compactMap { $0[keyPath: keyPath] }\n          #endif\n        }\n    }\n    #endif\n\n    /**\n     `Promise<[T]>` => `T` -> `Promise<U>` => `Promise<[U]>`\n\n         firstly {\n             .value([1,2,3])\n         }.thenMap { integer in\n             .value(integer * 2)\n         }.done {\n             // $0 => [2,4,6]\n         }\n     */\n    func thenMap<U: Thenable>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) throws -> U) -> Promise<[U.T]> {\n        return then(on: on, flags: flags) {\n            when(fulfilled: try $0.map(transform))\n        }\n    }\n\n    /**\n     `Promise<[T]>` => `T` -> `Promise<[U]>` => `Promise<[U]>`\n\n         firstly {\n             .value([1,2,3])\n         }.thenFlatMap { integer in\n             .value([integer, integer])\n         }.done {\n             // $0 => [1,1,2,2,3,3]\n         }\n     */\n    func thenFlatMap<U: Thenable>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) throws -> U) -> Promise<[U.T.Iterator.Element]> where U.T: Sequence {\n        return then(on: on, flags: flags) {\n            when(fulfilled: try $0.map(transform))\n        }.map(on: nil) {\n            $0.flatMap{ $0 }\n        }\n    }\n\n    /**\n     `Promise<[T]>` => `T` -> Bool => `Promise<[T]>`\n\n         firstly {\n             .value([1,2,3])\n         }.filterValues {\n             $0 > 1\n         }.done {\n             // $0 => [2,3]\n         }\n     */\n    func filterValues(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ isIncluded: @escaping (T.Iterator.Element) -> Bool) -> Promise<[T.Iterator.Element]> {\n        return map(on: on, flags: flags) {\n            $0.filter(isIncluded)\n        }\n    }\n\n    #if swift(>=4) && !swift(>=5.2)\n    /**\n     `Promise<[T]>` => `KeyPath<T, Bool>` => `Promise<[T]>`\n\n         firstly {\n             .value([Person(name: \"Max\"), Person(name: \"Roman\", age: 26, isStudent: false), Person(name: \"John\", age: 23, isStudent: true)])\n         }.filterValues(\\.isStudent).done {\n             // $0 => [Person(name: \"John\", age: 23, isStudent: true)]\n         }\n     */\n    func filterValues(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ keyPath: KeyPath<T.Iterator.Element, Bool>) -> Promise<[T.Iterator.Element]> {\n        return map(on: on, flags: flags) {\n            $0.filter { $0[keyPath: keyPath] }\n        }\n    }\n    #endif\n}\n\npublic extension Thenable where T: Collection {\n    /// - Returns: a promise fulfilled with the first value of this `Collection` or, if empty, a promise rejected with PMKError.emptySequence.\n    var firstValue: Promise<T.Iterator.Element> {\n        return map(on: nil) { aa in\n            if let a1 = aa.first {\n                return a1\n            } else {\n                throw PMKError.emptySequence\n            }\n        }\n    }\n\n    func firstValue(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, where test: @escaping (T.Iterator.Element) -> Bool) -> Promise<T.Iterator.Element> {\n        return map(on: on, flags: flags) {\n            for x in $0 where test(x) {\n                return x\n            }\n            throw PMKError.emptySequence\n        }\n    }\n\n    /// - Returns: a promise fulfilled with the last value of this `Collection` or, if empty, a promise rejected with PMKError.emptySequence.\n    var lastValue: Promise<T.Iterator.Element> {\n        return map(on: nil) { aa in\n            if aa.isEmpty {\n                throw PMKError.emptySequence\n            } else {\n                let i = aa.index(aa.endIndex, offsetBy: -1)\n                return aa[i]\n            }\n        }\n    }\n}\n\npublic extension Thenable where T: Sequence, T.Iterator.Element: Comparable {\n    /// - Returns: a promise fulfilled with the sorted values of this `Sequence`.\n    func sortedValues(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil) -> Promise<[T.Iterator.Element]> {\n        return map(on: on, flags: flags){ $0.sorted() }\n    }\n}\n"
  },
  {
    "path": "Sources/after.m",
    "content": "#import \"AnyPromise.h\"\n@import Dispatch;\n@import Foundation.NSDate;\n@import Foundation.NSValue;\n\n/// @return A promise that fulfills after the specified duration.\nAnyPromise *PMKAfter(NSTimeInterval duration) {\n    return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC));\n        dispatch_after(time, dispatch_get_global_queue(QOS_CLASS_UNSPECIFIED, 0), ^{\n            resolve(@(duration));\n        });\n    }];\n}\n"
  },
  {
    "path": "Sources/after.swift",
    "content": "import struct Foundation.TimeInterval\nimport Dispatch\n\n/**\n     after(seconds: 1.5).then {\n         //…\n     }\n\n- Returns: A guarantee that resolves after the specified duration.\n*/\npublic func after(seconds: TimeInterval) -> Guarantee<Void> {\n    let (rg, seal) = Guarantee<Void>.pending()\n    let when = DispatchTime.now() + seconds\n#if swift(>=4.0)\n    q.asyncAfter(deadline: when) { seal(()) }\n#else\n    q.asyncAfter(deadline: when, execute: seal)\n#endif\n    return rg\n}\n\n/**\n     after(.seconds(2)).then {\n         //…\n     }\n\n - Returns: A guarantee that resolves after the specified duration.\n*/\npublic func after(_ interval: DispatchTimeInterval) -> Guarantee<Void> {\n    let (rg, seal) = Guarantee<Void>.pending()\n    let when = DispatchTime.now() + interval\n#if swift(>=4.0)\n    q.asyncAfter(deadline: when) { seal(()) }\n#else\n    q.asyncAfter(deadline: when, execute: seal)\n#endif\n    return rg\n}\n\nprivate var q: DispatchQueue {\n    if #available(macOS 10.10, iOS 8.0, tvOS 9.0, watchOS 2.0, *) {\n        return DispatchQueue.global(qos: .default)\n    } else {\n        return DispatchQueue.global(priority: .default)\n    }\n}\n"
  },
  {
    "path": "Sources/dispatch_promise.m",
    "content": "#import \"AnyPromise.h\"\n@import Dispatch;\n\nAnyPromise *dispatch_promise_on(dispatch_queue_t queue, id block) {\n    return [AnyPromise promiseWithValue:nil].thenOn(queue, block);\n}\n\nAnyPromise *dispatch_promise(id block) {\n    return dispatch_promise_on(dispatch_get_global_queue(QOS_CLASS_UNSPECIFIED, 0), block);\n}\n"
  },
  {
    "path": "Sources/firstly.swift",
    "content": "import Dispatch\n\n/**\n Judicious use of `firstly` *may* make chains more readable.\n\n Compare:\n\n     URLSession.shared.dataTask(url: url1).then {\n         URLSession.shared.dataTask(url: url2)\n     }.then {\n         URLSession.shared.dataTask(url: url3)\n     }\n\n With:\n\n     firstly {\n         URLSession.shared.dataTask(url: url1)\n     }.then {\n         URLSession.shared.dataTask(url: url2)\n     }.then {\n         URLSession.shared.dataTask(url: url3)\n     }\n\n - Note: the block you pass executes immediately on the current thread/queue.\n */\npublic func firstly<U: Thenable>(execute body: () throws -> U) -> Promise<U.T> {\n    do {\n        let rp = Promise<U.T>(.pending)\n        try body().pipe(to: rp.box.seal)\n        return rp\n    } catch {\n        return Promise(error: error)\n    }\n}\n\n/// - See: firstly()\npublic func firstly<T>(execute body: () -> Guarantee<T>) -> Guarantee<T> {\n    return body()\n}\n"
  },
  {
    "path": "Sources/fwd.h",
    "content": "#import <Foundation/NSDate.h>\n#import <dispatch/dispatch.h>\n\n@class AnyPromise;\nextern NSString * __nonnull const PMKErrorDomain;\n\n#define PMKFailingPromiseIndexKey @\"PMKFailingPromiseIndexKey\"\n#define PMKJoinPromisesKey @\"PMKJoinPromisesKey\"\n\n#define PMKUnexpectedError 1l\n#define PMKInvalidUsageError 3l\n#define PMKAccessDeniedError 4l\n#define PMKOperationFailed 8l\n#define PMKTaskError 9l\n#define PMKJoinError 10l\n#define PMKNoWinnerError 11l\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n @return A new promise that resolves after the specified duration.\n\n @parameter duration The duration in seconds to wait before this promise is resolve.\n\n For example:\n\n    PMKAfter(1).then(^{\n        //…\n    });\n*/\nextern AnyPromise * __nonnull PMKAfter(NSTimeInterval duration) NS_REFINED_FOR_SWIFT;\n\n\n\n/**\n `when` is a mechanism for waiting more than one asynchronous task and responding when they are all complete.\n\n `PMKWhen` accepts varied input. If an array is passed then when those promises fulfill, when’s promise fulfills with an array of fulfillment values. If a dictionary is passed then the same occurs, but when’s promise fulfills with a dictionary of fulfillments keyed as per the input.\n\n Interestingly, if a single promise is passed then when waits on that single promise, and if a single non-promise object is passed then when fulfills immediately with that object. If the array or dictionary that is passed contains objects that are not promises, then these objects are considered fulfilled promises. The reason we do this is to allow a pattern know as \"abstracting away asynchronicity\".\n\n If *any* of the provided promises reject, the returned promise is immediately rejected with that promise’s rejection. The error’s `userInfo` object is supplemented with `PMKFailingPromiseIndexKey`.\n\n For example:\n\n    PMKWhen(@[promise1, promise2]).then(^(NSArray *results){\n        //…\n    });\n\n @warning *Important* In the event of rejection the other promises will continue to resolve and as per any other promise will either fulfill or reject. This is the right pattern for `getter` style asynchronous tasks, but often for `setter` tasks (eg. storing data on a server), you most likely will need to wait on all tasks and then act based on which have succeeded and which have failed. In such situations use `PMKJoin`.\n\n @param input The input upon which to wait before resolving this promise.\n\n @return A promise that is resolved with either:\n\n  1. An array of values from the provided array of promises.\n  2. The value from the provided promise.\n  3. The provided non-promise object.\n\n @see PMKJoin\n\n*/\nextern AnyPromise * __nonnull PMKWhen(id __nonnull input) NS_REFINED_FOR_SWIFT;\n\n\n\n/**\n Creates a new promise that resolves only when all provided promises have resolved.\n\n Typically, you should use `PMKWhen`.\n\n For example:\n\n    PMKJoin(@[promise1, promise2]).then(^(NSArray *resultingValues){\n        //…\n    }).catch(^(NSError *error){\n        assert(error.domain == PMKErrorDomain);\n        assert(error.code == PMKJoinError);\n\n        NSArray *promises = error.userInfo[PMKJoinPromisesKey];\n        for (AnyPromise *promise in promises) {\n            if (promise.rejected) {\n                //…\n            }\n        }\n    });\n\n @param promises An array of promises.\n\n @return A promise that thens three parameters:\n\n  1) An array of mixed values and errors from the resolved input.\n  2) An array of values from the promises that fulfilled.\n  3) An array of errors from the promises that rejected or nil if all promises fulfilled.\n\n @see when\n*/\nAnyPromise *__nonnull PMKJoin(NSArray * __nonnull promises) NS_REFINED_FOR_SWIFT;\n\n\n\n/**\n Literally hangs this thread until the promise has resolved.\n \n Do not use hang… unless you are testing, playing or debugging.\n \n If you use it in production code I will literally and honestly cry like a child.\n \n @return The resolved value of the promise.\n\n @warning T SAFE. IT IS NOT SAFE. IT IS NOT SAFE. IT IS NOT SAFE. IT IS NO\n*/\nextern id __nullable PMKHang(AnyPromise * __nonnull promise);\n\n\n\n/**\n Executes the provided block on a background queue.\n\n dispatch_promise is a convenient way to start a promise chain where the\n first step needs to run synchronously on a background queue.\n\n    dispatch_promise(^{\n        return md5(input);\n    }).then(^(NSString *md5){\n        NSLog(@\"md5: %@\", md5);\n    });\n\n @param block The block to be executed in the background. Returning an `NSError` will reject the promise, everything else (including void) fulfills the promise.\n\n @return A promise resolved with the return value of the provided block.\n\n @see dispatch_async\n*/\nextern AnyPromise * __nonnull dispatch_promise(id __nonnull block) NS_SWIFT_UNAVAILABLE(\"Use our `DispatchQueue.async` override instead\");\n\n\n\n/**\n Executes the provided block on the specified background queue.\n\n    dispatch_promise_on(myDispatchQueue, ^{\n        return md5(input);\n    }).then(^(NSString *md5){\n        NSLog(@\"md5: %@\", md5);\n    });\n\n @param block The block to be executed in the background. Returning an `NSError` will reject the promise, everything else (including void) fulfills the promise.\n\n @return A promise resolved with the return value of the provided block.\n\n @see dispatch_promise\n*/\nextern AnyPromise * __nonnull dispatch_promise_on(dispatch_queue_t __nonnull queue, id __nonnull block) NS_SWIFT_UNAVAILABLE(\"Use our `DispatchQueue.async` override instead\");\n\n/**\n Returns a new promise that resolves when the value of the first resolved promise in the provided array of promises.\n*/\nextern AnyPromise * __nonnull PMKRace(NSArray * __nonnull promises) NS_REFINED_FOR_SWIFT;\n\n/**\n Returns a new promise that resolves with the value of the first fulfilled promise in the provided array of promises.\n*/\nextern AnyPromise * __nonnull PMKRaceFulfilled(NSArray * __nonnull promises) NS_REFINED_FOR_SWIFT;\n\n#ifdef __cplusplus\n}   // Extern C\n#endif\n"
  },
  {
    "path": "Sources/hang.m",
    "content": "#import \"AnyPromise.h\"\n#import \"AnyPromise+Private.h\"\n@import CoreFoundation.CFRunLoop;\n\n/**\n Suspends the active thread waiting on the provided promise.\n\n @return The value of the provided promise once resolved. \n */\nid PMKHang(AnyPromise *promise) {\n    if (promise.pending) {\n        static CFRunLoopSourceContext context;\n\n        CFRunLoopRef runLoop = CFRunLoopGetCurrent();\n        CFRunLoopSourceRef runLoopSource = CFRunLoopSourceCreate(NULL, 0, &context);\n        CFRunLoopAddSource(runLoop, runLoopSource, kCFRunLoopDefaultMode);\n\n        promise.ensure(^{\n            CFRunLoopStop(runLoop);\n        });\n        while (promise.pending) {\n            CFRunLoopRun();\n        }\n        CFRunLoopRemoveSource(runLoop, runLoopSource, kCFRunLoopDefaultMode);\n        CFRelease(runLoopSource);\n    }\n\n    return promise.value;\n}\n"
  },
  {
    "path": "Sources/hang.swift",
    "content": "import Foundation\nimport CoreFoundation\n\n/**\n Runs the active run-loop until the provided promise resolves.\n\n This is for debug and is not a generally safe function to use in your applications. We mostly provide it for use in testing environments.\n\n Still if you like, study how it works (by reading the sources!) and use at your own risk.\n\n - Returns: The value of the resolved promise\n - Throws: An error, should the promise be rejected\n - See: `wait()`\n*/\npublic func hang<T>(_ promise: Promise<T>) throws -> T {\n#if os(Linux) || os(Android)\n#if swift(>=4)\n    let runLoopMode: CFRunLoopMode = kCFRunLoopDefaultMode\n#else\n    // isMainThread is not yet implemented on Linux.\n    let runLoopModeRaw = RunLoopMode.defaultRunLoopMode.rawValue._bridgeToObjectiveC()\n    let runLoopMode: CFString = unsafeBitCast(runLoopModeRaw, to: CFString.self)\n#endif\n#else\n    guard Thread.isMainThread else {\n        // hang doesn't make sense on threads that aren't the main thread.\n        // use `.wait()` on those threads.\n        fatalError(\"Only call hang() on the main thread.\")\n    }\n    let runLoopMode: CFRunLoopMode = CFRunLoopMode.defaultMode\n#endif\n\n    if promise.isPending {\n        var context = CFRunLoopSourceContext()\n        let runLoop = CFRunLoopGetCurrent()\n        let runLoopSource = CFRunLoopSourceCreate(nil, 0, &context)\n        CFRunLoopAddSource(runLoop, runLoopSource, runLoopMode)\n\n        _ = promise.ensure {\n            CFRunLoopStop(runLoop)\n        }\n\n        while promise.isPending {\n            CFRunLoopRun()\n        }\n        CFRunLoopRemoveSource(runLoop, runLoopSource, runLoopMode)\n    }\n\n    switch promise.result! {\n    case .rejected(let error):\n        throw error\n    case .fulfilled(let value):\n        return value\n    }\n}\n"
  },
  {
    "path": "Sources/join.m",
    "content": "@import Foundation.NSDictionary;\n#import \"AnyPromise+Private.h\"\n#import <libkern/OSAtomic.h>\n@import Foundation.NSError;\n@import Foundation.NSNull;\n#import \"PromiseKit.h\"\n#import <stdatomic.h>\n\n/**\n Waits on all provided promises.\n\n `PMKWhen` rejects as soon as one of the provided promises rejects. `PMKJoin` waits on all provided promises, then rejects if any of those promises rejects, otherwise it fulfills with values from the provided promises.\n\n - Returns: A new promise that resolves once all the provided promises resolve.\n*/\nAnyPromise *PMKJoin(NSArray *promises) {\n    if (promises == nil)\n        return [AnyPromise promiseWithValue:[NSError errorWithDomain:PMKErrorDomain code:PMKInvalidUsageError userInfo:@{NSLocalizedDescriptionKey: @\"PMKJoin(nil)\"}]];\n\n    if (promises.count == 0)\n        return [AnyPromise promiseWithValue:promises];\n\n    return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        NSPointerArray *results = NSPointerArrayMake(promises.count);\n        __block atomic_int countdown = promises.count;\n        __block BOOL rejected = NO;\n\n        [promises enumerateObjectsUsingBlock:^(AnyPromise *promise, NSUInteger ii, BOOL *stop) {\n            [promise __pipe:^(id value) {\n\n                if (IsError(value)) {\n                    rejected = YES;\n                }\n\n                //FIXME surely this isn't thread safe on multiple cores?\n                [results replacePointerAtIndex:ii withPointer:(__bridge void *)(value ?: [NSNull null])];\n\n                atomic_fetch_sub_explicit(&countdown, 1, memory_order_relaxed);\n\n                if (countdown == 0) {\n                    if (!rejected) {\n                        resolve(results.allObjects);\n                    } else {\n                        id userInfo = @{PMKJoinPromisesKey: promises};\n                        id err = [NSError errorWithDomain:PMKErrorDomain code:PMKJoinError userInfo:userInfo];\n                        resolve(err);\n                    }\n                }\n            }];\n\n            (void) stop;\n        }];\n    }];\n}\n"
  },
  {
    "path": "Sources/race.m",
    "content": "#import \"AnyPromise+Private.h\"\n#import <libkern/OSAtomic.h>\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n// ^^ OSAtomicDecrement32 is deprecated on watchOS\n\nAnyPromise *PMKRace(NSArray *promises) {\n    if (promises == nil || promises.count == 0)\n        return [AnyPromise promiseWithValue:[NSError errorWithDomain:PMKErrorDomain code:PMKInvalidUsageError userInfo:@{NSLocalizedDescriptionKey: @\"PMKRace(nil)\"}]];\n\n    return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        for (AnyPromise *promise in promises) {\n            [promise __pipe:resolve];\n        }\n    }];\n}\n\n/**\n Waits for one promise to fulfill\n\n @note If there are no fulfilled promises, the returned promise is rejected with `PMKNoWinnerError`.\n @param promises The promises to fulfill.\n @return The promise that was fulfilled first.\n*/\nAnyPromise *PMKRaceFulfilled(NSArray *promises) {\n    if (promises == nil || promises.count == 0)\n        return [AnyPromise promiseWithValue:[NSError errorWithDomain:PMKErrorDomain code:PMKInvalidUsageError userInfo:@{NSLocalizedDescriptionKey: @\"PMKRaceFulfilled(nil)\"}]];\n\n    __block int32_t countdown = (int32_t)[promises count];\n\n    return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        for (__strong AnyPromise* promise in promises) {\n            [promise __pipe:^(id value) {\n                if (IsError(value)) {\n                    if (OSAtomicDecrement32(&countdown) == 0) {\n                        id err = [NSError errorWithDomain:PMKErrorDomain code:PMKNoWinnerError userInfo:@{NSLocalizedDescriptionKey: @\"PMKRaceFulfilled(nil)\"}];\n                        resolve(err);\n                    }\n                } else {\n                    resolve(value);\n                }\n            }];\n        }\n    }];\n}\n\n#pragma GCC diagnostic pop\n"
  },
  {
    "path": "Sources/race.swift",
    "content": "import Dispatch\n\n@inline(__always)\nprivate func _race<U: Thenable>(_ thenables: [U]) -> Promise<U.T> {\n    let rp = Promise<U.T>(.pending)\n    for thenable in thenables {\n        thenable.pipe(to: rp.box.seal)\n    }\n    return rp\n}\n\n/**\n Waits for one promise to resolve\n\n     race(promise1, promise2, promise3).then { winner in\n         //…\n     }\n\n - Returns: The promise that resolves first\n - Warning: If the first resolution is a rejection, the returned promise is rejected\n*/\npublic func race<U: Thenable>(_ thenables: U...) -> Promise<U.T> {\n    return _race(thenables)\n}\n\n/**\n Waits for one promise to resolve\n\n     race(promise1, promise2, promise3).then { winner in\n         //…\n     }\n\n - Returns: The promise that resolves first\n - Warning: If the first resolution is a rejection, the returned promise is rejected\n - Remark: If the provided array is empty the returned promise is rejected with PMKError.badInput\n*/\npublic func race<U: Thenable>(_ thenables: [U]) -> Promise<U.T> {\n    guard !thenables.isEmpty else {\n        return Promise(error: PMKError.badInput)\n    }\n    return _race(thenables)\n}\n\n/**\n Waits for one guarantee to resolve\n\n     race(promise1, promise2, promise3).then { winner in\n         //…\n     }\n\n - Returns: The guarantee that resolves first\n*/\npublic func race<T>(_ guarantees: Guarantee<T>...) -> Guarantee<T> {\n    let rg = Guarantee<T>(.pending)\n    for guarantee in guarantees {\n        guarantee.pipe(to: rg.box.seal)\n    }\n    return rg\n}\n\n/**\n Waits for one promise to fulfill\n\n     race(fulfilled: [promise1, promise2, promise3]).then { winner in\n         //…\n     }\n\n - Returns: The promise that was fulfilled first.\n - Warning: Skips all rejected promises.\n - Remark: If the provided array is empty, the returned promise is rejected with `PMKError.badInput`. If there are no fulfilled promises, the returned promise is rejected with `PMKError.noWinner`.\n*/\npublic func race<U: Thenable>(fulfilled thenables: [U]) -> Promise<U.T> {\n    var countdown = thenables.count\n    guard countdown > 0 else {\n        return Promise(error: PMKError.badInput)\n    }\n\n    let rp = Promise<U.T>(.pending)\n\n    let barrier = DispatchQueue(label: \"org.promisekit.barrier.race\", attributes: .concurrent)\n\n    for promise in thenables {\n        promise.pipe { result in\n            barrier.sync(flags: .barrier) {\n                switch result {\n                case .rejected:\n                    guard rp.isPending else { return }\n                    countdown -= 1\n                    if countdown == 0 {\n                        rp.box.seal(.rejected(PMKError.noWinner))\n                    }\n                case .fulfilled(let value):\n                    guard rp.isPending else { return }\n                    countdown = 0\n                    rp.box.seal(.fulfilled(value))\n                }\n            }\n        }\n    }\n\n    return rp\n}\n"
  },
  {
    "path": "Sources/when.m",
    "content": "@import Foundation.NSDictionary;\n#import \"AnyPromise+Private.h\"\n@import Foundation.NSProgress;\n#import <libkern/OSAtomic.h>\n@import Foundation.NSError;\n@import Foundation.NSNull;\n#import \"PromiseKit.h\"\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n// ^^ OSAtomicDecrement32 is deprecated on watchOS\n\n\n// NSProgress resources:\n//  * https://robots.thoughtbot.com/asynchronous-nsprogress\n//  * http://oleb.net/blog/2014/03/nsprogress/\n// NSProgress! Beware!\n//  * https://github.com/AFNetworking/AFNetworking/issues/2261\n\n/**\n Wait for all promises in a set to resolve.\n\n @note If *any* of the provided promises reject, the returned promise is immediately rejected with that error.\n @warning In the event of rejection the other promises will continue to resolve and, as per any other promise, will either fulfill or reject. This is the right pattern for `getter` style asynchronous tasks, but often for `setter` tasks (eg. storing data on a server), you most likely will need to wait on all tasks and then act based on which have succeeded and which have failed, in such situations use `when(resolved:)`.\n @param promises The promises upon which to wait before the returned promise resolves.\n @note PMKWhen provides NSProgress.\n @return A new promise that resolves when all the provided promises fulfill or one of the provided promises rejects.\n*/\nAnyPromise *PMKWhen(id promises) {\n    if (promises == nil)\n        return [AnyPromise promiseWithValue:[NSError errorWithDomain:PMKErrorDomain code:PMKInvalidUsageError userInfo:@{NSLocalizedDescriptionKey: @\"PMKWhen(nil)\"}]];\n\n    if ([promises isKindOfClass:[NSArray class]] || [promises isKindOfClass:[NSDictionary class]]) {\n        if ([promises count] == 0)\n            return [AnyPromise promiseWithValue:promises];\n    } else if ([promises isKindOfClass:[AnyPromise class]]) {\n        promises = @[promises];\n    } else {\n        return [AnyPromise promiseWithValue:promises];\n    }\n\n#ifndef PMKDisableProgress\n    NSProgress *progress = [NSProgress progressWithTotalUnitCount:(int64_t)[promises count]];\n    progress.pausable = NO;\n    progress.cancellable = NO;\n#else\n    struct PMKProgress {\n        int completedUnitCount;\n        int totalUnitCount;\n        double fractionCompleted;\n    };\n    __block struct PMKProgress progress;\n#endif\n\n    __block int32_t countdown = (int32_t)[promises count];\n    BOOL const isdict = [promises isKindOfClass:[NSDictionary class]];\n\n    return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        NSInteger index = 0;\n\n        for (__strong id key in promises) {\n            AnyPromise *promise = isdict ? promises[key] : key;\n            if (!isdict) key = @(index);\n\n            if (![promise isKindOfClass:[AnyPromise class]])\n                promise = [AnyPromise promiseWithValue:promise];\n\n            [promise __pipe:^(id value){\n                if (progress.fractionCompleted >= 1)\n                    return;\n\n                if (IsError(value)) {\n                    progress.completedUnitCount = progress.totalUnitCount;\n\n                    NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:[(NSError *)value userInfo] ?: @{}];\n                    userInfo[PMKFailingPromiseIndexKey] = key;\n                    [userInfo setObject:value forKey:NSUnderlyingErrorKey];\n                    id err = [[NSError alloc] initWithDomain:[value domain] code:[value code] userInfo:userInfo];\n                    resolve(err);\n                }\n                else if (OSAtomicDecrement32(&countdown) == 0) {\n                    progress.completedUnitCount = progress.totalUnitCount;\n\n                    id results;\n                    if (isdict) {\n                        results = [NSMutableDictionary new];\n                        for (id key in promises) {\n                            id promise = promises[key];\n                            results[key] = IsPromise(promise) ? ((AnyPromise *)promise).value : promise;\n                        }\n                    } else {\n                        results = [NSMutableArray new];\n                        for (AnyPromise *promise in promises) {\n                            id value = IsPromise(promise) ? (promise.value ?: [NSNull null]) : promise;\n                            [results addObject:value];\n                        }\n                    }\n                    resolve(results);\n                } else {\n                    progress.completedUnitCount++;\n                }\n            }];\n        }\n    }];\n}\n\n#pragma GCC diagnostic pop\n"
  },
  {
    "path": "Sources/when.swift",
    "content": "import Foundation\nimport Dispatch\n\nprivate func _when<U: Thenable>(_ thenables: [U]) -> Promise<Void> {\n    var countdown = thenables.count\n    guard countdown > 0 else {\n        return .value(Void())\n    }\n\n    let rp = Promise<Void>(.pending)\n\n#if PMKDisableProgress || os(Linux)\n    var progress: (completedUnitCount: Int, totalUnitCount: Int) = (0, 0)\n#else\n    let progress = Progress(totalUnitCount: Int64(thenables.count))\n    progress.isCancellable = false\n    progress.isPausable = false\n#endif\n\n    let barrier = DispatchQueue(label: \"org.promisekit.barrier.when\", attributes: .concurrent)\n\n    for promise in thenables {\n        promise.pipe { result in\n            barrier.sync(flags: .barrier) {\n                switch result {\n                case .rejected(let error):\n                    if rp.isPending {\n                        progress.completedUnitCount = progress.totalUnitCount\n                        rp.box.seal(.rejected(error))\n                    }\n                case .fulfilled:\n                    guard rp.isPending else { return }\n                    progress.completedUnitCount += 1\n                    countdown -= 1\n                    if countdown == 0 {\n                        rp.box.seal(.fulfilled(()))\n                    }\n                }\n            }\n        }\n    }\n\n    return rp\n}\n\nprivate func __when<T>(_ guarantees: [Guarantee<T>]) -> Guarantee<Void> {\n    var countdown = guarantees.count\n    guard countdown > 0 else {\n        return .value(Void())\n    }\n\n    let rg = Guarantee<Void>(.pending)\n\n#if PMKDisableProgress || os(Linux)\n    var progress: (completedUnitCount: Int, totalUnitCount: Int) = (0, 0)\n#else\n    let progress = Progress(totalUnitCount: Int64(guarantees.count))\n    progress.isCancellable = false\n    progress.isPausable = false\n#endif\n\n    let barrier = DispatchQueue(label: \"org.promisekit.barrier.when\", attributes: .concurrent)\n\n    for guarantee in guarantees {\n        guarantee.pipe { (_: T) in\n            barrier.sync(flags: .barrier) {\n                guard rg.isPending else { return }\n                progress.completedUnitCount += 1\n                countdown -= 1\n                if countdown == 0 {\n                    rg.box.seal(())\n                }\n            }\n        }\n    }\n\n    return rg\n}\n\n/**\n Wait for all promises in a set to fulfill.\n\n For example:\n\n     when(fulfilled: promise1, promise2).then { results in\n         //…\n     }.catch { error in\n         switch error {\n         case URLError.notConnectedToInternet:\n             //…\n         case CLError.denied:\n             //…\n         }\n     }\n\n - Note: If *any* of the provided promises reject, the returned promise is immediately rejected with that error.\n - Warning: In the event of rejection the other promises will continue to resolve and, as per any other promise, will either fulfill or reject. This is the right pattern for `getter` style asynchronous tasks, but often for `setter` tasks (eg. storing data on a server), you most likely will need to wait on all tasks and then act based on which have succeeded and which have failed, in such situations use `when(resolved:)`.\n - Parameter promises: The promises upon which to wait before the returned promise resolves.\n - Returns: A new promise that resolves when all the provided promises fulfill or one of the provided promises rejects.\n - Note: `when` provides `NSProgress`.\n - SeeAlso: `when(resolved:)`\n*/\npublic func when<U: Thenable>(fulfilled thenables: [U]) -> Promise<[U.T]> {\n    return _when(thenables).map(on: nil) { thenables.map{ $0.value! } }\n}\n\n#if swift(>=5.7)\npublic func when(fulfilled thenables: [any Thenable]) -> Promise<[Any]> {\n    return _when(thenables.map { $0.asVoid()}).map(on: nil) { thenables.map { $0.value! } }\n}\n#endif\n\n#if swift(>=5.9)\npublic func when<each U: Thenable>(fulfilled: repeat each U) -> Promise<(repeat (each U).T)> {\n    var voidPromises: [Promise<Void>] = []\n    repeat voidPromises.append((each fulfilled).asVoid())\n    return _when(voidPromises).map(on: nil) { (repeat (each fulfilled).value!) }\n}\n#endif\n\n/// Wait for all promises in a set to fulfill.\npublic func when<U: Thenable>(fulfilled promises: U...) -> Promise<Void> where U.T == Void {\n    return _when(promises)\n}\n\n/// Wait for all promises in a set to fulfill.\npublic func when<U: Thenable>(fulfilled promises: [U]) -> Promise<Void> where U.T == Void {\n    return _when(promises)\n}\n\n/// Wait for all promises in a set to fulfill.\npublic func when<U: Thenable, V: Thenable>(fulfilled pu: U, _ pv: V) -> Promise<(U.T, V.T)> {\n    return _when([pu.asVoid(), pv.asVoid()]).map(on: nil) { (pu.value!, pv.value!) }\n}\n\n/// Wait for all promises in a set to fulfill.\npublic func when<U: Thenable, V: Thenable, W: Thenable>(fulfilled pu: U, _ pv: V, _ pw: W) -> Promise<(U.T, V.T, W.T)> {\n    return _when([pu.asVoid(), pv.asVoid(), pw.asVoid()]).map(on: nil) { (pu.value!, pv.value!, pw.value!) }\n}\n\n/// Wait for all promises in a set to fulfill.\npublic func when<U: Thenable, V: Thenable, W: Thenable, X: Thenable>(fulfilled pu: U, _ pv: V, _ pw: W, _ px: X) -> Promise<(U.T, V.T, W.T, X.T)> {\n    return _when([pu.asVoid(), pv.asVoid(), pw.asVoid(), px.asVoid()]).map(on: nil) { (pu.value!, pv.value!, pw.value!, px.value!) }\n}\n\n/// Wait for all promises in a set to fulfill.\npublic func when<U: Thenable, V: Thenable, W: Thenable, X: Thenable, Y: Thenable>(fulfilled pu: U, _ pv: V, _ pw: W, _ px: X, _ py: Y) -> Promise<(U.T, V.T, W.T, X.T, Y.T)> {\n    return _when([pu.asVoid(), pv.asVoid(), pw.asVoid(), px.asVoid(), py.asVoid()]).map(on: nil) { (pu.value!, pv.value!, pw.value!, px.value!, py.value!) }\n}\n\n/**\n Generate promises at a limited rate and wait for all to fulfill.\n\n For example:\n \n     func downloadFile(url: URL) -> Promise<Data> {\n         // ...\n     }\n \n     let urls: [URL] = /*…*/\n     let urlGenerator = urls.makeIterator()\n\n     let generator = AnyIterator<Promise<Data>> {\n         guard url = urlGenerator.next() else {\n             return nil\n         }\n         return downloadFile(url)\n     }\n\n     when(generator, concurrently: 3).done { datas in\n         // ...\n     }\n \n No more than three downloads will occur simultaneously.\n\n - Note: The generator is called *serially* on a *background* queue.\n - Warning: Refer to the warnings on `when(fulfilled:)`\n - Parameter promiseGenerator: Generator of promises.\n - Returns: A new promise that resolves when all the provided promises fulfill or one of the provided promises rejects.\n - SeeAlso: `when(resolved:)`\n */\n\npublic func when<It: IteratorProtocol>(fulfilled promiseIterator: It, concurrently: Int) -> Promise<[It.Element.T]> where It.Element: Thenable {\n\n    guard concurrently > 0 else {\n        return Promise(error: PMKError.badInput)\n    }\n\n    var generator = promiseIterator\n    let root = Promise<[It.Element.T]>.pending()\n    var pendingPromises = 0\n    var promises: [It.Element] = []\n\n    let barrier = DispatchQueue(label: \"org.promisekit.barrier.when\", attributes: [.concurrent])\n\n    func dequeue() {\n        guard root.promise.isPending else { return }  // don’t continue dequeueing if root has been rejected\n\n        var shouldDequeue = false\n        barrier.sync {\n            shouldDequeue = pendingPromises < concurrently\n        }\n        guard shouldDequeue else { return }\n\n        var promise: It.Element!\n\n        barrier.sync(flags: .barrier) {\n            guard let next = generator.next() else { return }\n            promise = next\n            pendingPromises += 1\n            promises.append(next)\n        }\n\n        func testDone() {\n            barrier.sync {\n                if pendingPromises == 0 {\n                  #if !swift(>=3.3) || (swift(>=4) && !swift(>=4.1))\n                    root.resolver.fulfill(promises.flatMap{ $0.value })\n                  #else\n                    root.resolver.fulfill(promises.compactMap{ $0.value })\n                  #endif\n                }\n            }\n        }\n\n        guard promise != nil else {\n            return testDone()\n        }\n\n        promise.pipe { resolution in\n            barrier.sync(flags: .barrier) {\n                pendingPromises -= 1\n            }\n\n            switch resolution {\n            case .fulfilled:\n                dequeue()\n                testDone()\n            case .rejected(let error):\n                root.resolver.reject(error)\n            }\n        }\n\n        dequeue()\n    }\n        \n    dequeue()\n\n    return root.promise\n}\n\n/**\n Waits on all provided promises.\n\n `when(fulfilled:)` rejects as soon as one of the provided promises rejects. `when(resolved:)` waits on all provided promises whatever their result, and then provides an array of `Result<T>` so you can individually inspect the results. As a consequence this function returns a `Guarantee`, ie. errors are lifted from the individual promises into the results array of the returned `Guarantee`.\n\n     when(resolved: promise1, promise2, promise3).then { results in\n         for result in results where case .fulfilled(let value) {\n            //…\n         }\n     }.catch { error in\n         // invalid! Never rejects\n     }\n\n - Returns: A new promise that resolves once all the provided promises resolve. The array is ordered the same as the input, ie. the result order is *not* resolution order.\n - Note: we do not provide tuple variants for `when(resolved:)` but will accept a pull-request\n - Remark: Doesn't take Thenable due to protocol `associatedtype` paradox\n*/\npublic func when<T>(resolved promises: Promise<T>...) -> Guarantee<[Result<T>]> {\n    return when(resolved: promises)\n}\n\n/// - See: `when(resolved: Promise<T>...)`\npublic func when<T>(resolved promises: [Promise<T>]) -> Guarantee<[Result<T>]> {\n    guard !promises.isEmpty else {\n        return .value([])\n    }\n\n    var countdown = promises.count\n    let barrier = DispatchQueue(label: \"org.promisekit.barrier.join\", attributes: .concurrent)\n\n    let rg = Guarantee<[Result<T>]>(.pending)\n    for promise in promises {\n        promise.pipe { result in\n            barrier.sync(flags: .barrier) {\n                countdown -= 1\n            }\n            barrier.sync {\n                if countdown == 0 {\n                    rg.box.seal(promises.map{ $0.result! })\n                }\n            }\n        }\n    }\n    return rg\n}\n\n/**\nGenerate promises at a limited rate and wait for all to resolve.\n\nFor example:\n\n    func downloadFile(url: URL) -> Promise<Data> {\n        // ...\n    }\n\n    let urls: [URL] = /*…*/\n    let urlGenerator = urls.makeIterator()\n\n    let generator = AnyIterator<Promise<Data>> {\n        guard url = urlGenerator.next() else {\n            return nil\n        }\n        return downloadFile(url)\n    }\n\n    when(resolved: generator, concurrently: 3).done { results in\n        // ...\n    }\n\nNo more than three downloads will occur simultaneously. Downloads will continue if one of them fails\n\n- Note: The generator is called *serially* on a *background* queue.\n- Warning: Refer to the warnings on `when(resolved:)`\n- Parameter promiseGenerator: Generator of promises.\n- Returns: A new promise that resolves once all the provided promises resolve. The array is ordered the same as the input, ie. the result order is *not* resolution order.\n- SeeAlso: `when(resolved:)`\n*/\n#if swift(>=5.3)\npublic func when<It: IteratorProtocol>(resolved promiseIterator: It, concurrently: Int)\n    -> Guarantee<[Result<It.Element.T>]> where It.Element: Thenable {\n    guard concurrently > 0 else {\n        return Guarantee.value([Result.rejected(PMKError.badInput)])\n    }\n\n    var generator = promiseIterator\n    let root = Guarantee<[Result<It.Element.T>]>.pending()\n    var pendingPromises = 0\n    var promises: [It.Element] = []\n\n    let barrier = DispatchQueue(label: \"org.promisekit.barrier.when\", attributes: [.concurrent])\n\n    func dequeue() {\n        guard root.guarantee.isPending else {\n            return\n        }  // don’t continue dequeueing if root has been rejected\n\n        var shouldDequeue = false\n        barrier.sync {\n            shouldDequeue = pendingPromises < concurrently\n        }\n        guard shouldDequeue else {\n            return\n        }\n\n        var promise: It.Element!\n\n        barrier.sync(flags: .barrier) {\n            guard let next = generator.next() else {\n                return\n            }\n\n            promise = next\n\n            pendingPromises += 1\n            promises.append(next)\n        }\n\n        func testDone() {\n            barrier.sync {\n                if pendingPromises == 0 {\n                  #if !swift(>=3.3) || (swift(>=4) && !swift(>=4.1))\n                    root.resolve(promises.flatMap { $0.result })\n                  #else\n                    root.resolve(promises.compactMap { $0.result })\n                  #endif\n                }\n            }\n        }\n\n        guard promise != nil else {\n            return testDone()\n        }\n\n        promise.pipe { _ in\n            barrier.sync(flags: .barrier) {\n                pendingPromises -= 1\n            }\n\n            dequeue()\n            testDone()\n        }\n\n        dequeue()\n    }\n\n    dequeue()\n\n    return root.guarantee\n}\n#endif\n\n/// Waits on all provided Guarantees.\npublic func when(_ guarantees: Guarantee<Void>...) -> Guarantee<Void> {\n    return when(guarantees: guarantees)\n}\n\n/// Waits on all provided Guarantees.\npublic func when<T>(_ guarantees: Guarantee<T>...) -> Guarantee<[T]> {\n    return when(guarantees: guarantees)\n}\n\n/// Waits on all provided Guarantees.\npublic func when(guarantees: [Guarantee<Void>]) -> Guarantee<Void> {\n    return when(fulfilled: guarantees).recover{ _ in }.asVoid()\n}\n\n/// Waits on all provided Guarantees.\npublic func when<T>(guarantees: [Guarantee<T>]) -> Guarantee<[T]> {\n    return __when(guarantees).map(on: nil) { guarantees.map { $0.value! } }\n}\n\n/// Waits on all provided Guarantees.\npublic func when<U, V>(guarantees gu: Guarantee<U>, _ gv: Guarantee<V>) -> Guarantee<(U, V)> {\n    return __when([gu.asVoid(), gv.asVoid()]).map(on: nil) { (gu.value!, gv.value!) }\n}\n\n/// Waits on all provided Guarantees.\npublic func when<U, V, W>(guarantees gu: Guarantee<U>, _ gv: Guarantee<V>, _ gw: Guarantee<W>) -> Guarantee<(U, V, W)> {\n    return __when([gu.asVoid(), gv.asVoid(), gw.asVoid()]).map(on: nil) { (gu.value!, gv.value!, gw.value!) }\n}\n\n/// Waits on all provided Guarantees.\npublic func when<U, V, W, X>(guarantees gu: Guarantee<U>, _ gv: Guarantee<V>, _ gw: Guarantee<W>, _ gx: Guarantee<X>) -> Guarantee<(U, V, W, X)> {\n    return __when([gu.asVoid(), gv.asVoid(), gw.asVoid(), gx.asVoid()]).map(on: nil) { (gu.value!, gv.value!, gw.value!, gx.value!) }\n}\n\n/// Waits on all provided Guarantees.\npublic func when<U, V, W, X, Y>(guarantees gu: Guarantee<U>, _ gv: Guarantee<V>, _ gw: Guarantee<W>, _ gx: Guarantee<X>, _ gy: Guarantee<Y>) -> Guarantee<(U, V, W, X, Y)> {\n    return __when([gu.asVoid(), gv.asVoid(), gw.asVoid(), gx.asVoid(), gy.asVoid()]).map(on: nil) { (gu.value!, gv.value!, gw.value!, gx.value!, gy.value!) }\n}\n"
  },
  {
    "path": "Tests/A+/0.0.0.swift",
    "content": "import PromiseKit\nimport Dispatch\nimport XCTest\n\nenum Error: Swift.Error {\n    case dummy  // we reject with this when we don't intend to test against it\n    case sentinel(UInt32)\n}\n\nprivate let timeout: TimeInterval = 10\n\nextension XCTestCase {\n    func describe(_ description: String, file: StaticString = #file, line: UInt = #line, body: () throws -> Void) {\n\n        PromiseKit.conf.Q.map = .main\n\n        do {\n            try body()\n        } catch {\n            XCTFail(description, file: file, line: line)\n        }\n    }\n\n    func specify(_ description: String, file: StaticString = #file, line: UInt = #line, body: ((promise: Promise<Void>, fulfill: () -> Void, reject: (Error) -> Void), XCTestExpectation) throws -> Void) {\n        let expectation = self.expectation(description: description)\n        let (pending, seal) = Promise<Void>.pending()\n\n        do {\n            try body((pending, seal.fulfill_, seal.reject), expectation)\n            waitForExpectations(timeout: timeout) { err in\n                if let _ = err {\n                    XCTFail(\"wait failed: \\(description)\", file: file, line: line)\n                }\n            }\n        } catch {\n            XCTFail(description, file: file, line: line)\n        }\n    }\n\n    func testFulfilled(file: StaticString = #file, line: UInt = #line, body: @escaping (Promise<UInt32>, XCTestExpectation, UInt32) -> Void) {\n        testFulfilled(withExpectationCount: 1, file: file, line: line) {\n            body($0, $1.first!, $2)\n        }\n    }\n\n    func testRejected(file: StaticString = #file, line: UInt = #line, body: @escaping (Promise<UInt32>, XCTestExpectation, UInt32) -> Void) {\n        testRejected(withExpectationCount: 1, file: file, line: line) {\n            body($0, $1.first!, $2)\n        }\n    }\n\n    func testFulfilled(withExpectationCount: Int, file: StaticString = #file, line: UInt = #line, body: @escaping (Promise<UInt32>, [XCTestExpectation], UInt32) -> Void) {\n\n        let specify = mkspecify(withExpectationCount, file: file, line: line, body: body)\n\n        specify(\"already-fulfilled\") { value in\n            return (.value(value), {})\n        }\n        specify(\"immediately-fulfilled\") { value in\n            let (promise, seal) = Promise<UInt32>.pending()\n            return (promise, {\n                seal.fulfill(value)\n            })\n        }\n        specify(\"eventually-fulfilled\") { value in\n            let (promise, seal) = Promise<UInt32>.pending()\n            return (promise, {\n                after(ticks: 5) {\n                    seal.fulfill(value)\n                }\n            })\n        }\n    }\n\n    func testRejected(withExpectationCount: Int, file: StaticString = #file, line: UInt = #line, body: @escaping (Promise<UInt32>, [XCTestExpectation], UInt32) -> Void) {\n\n        let specify = mkspecify(withExpectationCount, file: file, line: line, body: body)\n\n        specify(\"already-rejected\") { sentinel in\n            return (Promise(error: Error.sentinel(sentinel)), {})\n        }\n        specify(\"immediately-rejected\") { sentinel in\n            let (promise, seal) = Promise<UInt32>.pending()\n            return (promise, {\n                seal.reject(Error.sentinel(sentinel))\n            })\n        }\n        specify(\"eventually-rejected\") { sentinel in\n            let (promise, seal) = Promise<UInt32>.pending()\n            return (promise, {\n                after(ticks: 50) {\n                    seal.reject(Error.sentinel(sentinel))\n                }\n            })\n        }\n    }\n\n\n/////////////////////////////////////////////////////////////////////////\n\n    private func mkspecify(_ numberOfExpectations: Int, file: StaticString, line: UInt, body: @escaping (Promise<UInt32>, [XCTestExpectation], UInt32) -> Void) -> (String, _ feed: (UInt32) -> (Promise<UInt32>, () -> Void)) -> Void {\n        return { desc, feed in\n            let value = arc4random()\n            let (promise, executeAfter) = feed(value)\n            let expectations = (1...numberOfExpectations).map {\n                self.expectation(description: \"\\(desc) (\\($0))\")\n            }\n            body(promise, expectations, value)\n            \n            executeAfter()\n            \n            self.waitForExpectations(timeout: timeout) { err in\n                if let _ = err {\n                    XCTFail(\"timed out: \\(desc)\", file: file, line: line)\n                }\n            }\n        }\n    }\n\n    func mkex() -> XCTestExpectation {\n        return expectation(description: \"\")\n    }\n}\n\nfunc after(ticks: Int, execute body: @escaping () -> Void) {\n    precondition(ticks > 0)\n\n    var ticks = ticks\n    func f() {\n        DispatchQueue.main.async {\n            ticks -= 1\n            if ticks == 0 {\n                body()\n            } else {\n                f()\n            }\n        }\n    }\n    f()\n}\n\nextension Promise {\n    func test(onFulfilled: @escaping () -> Void, onRejected: @escaping () -> Void) {\n        tap { result in\n            switch result {\n            case .fulfilled:\n                onFulfilled()\n            case .rejected:\n                onRejected()\n            }\n        }.silenceWarning()\n    }\n}\n\nprefix func ++(a: inout Int) -> Int {\n    a += 1\n    return a\n}\n\nextension Promise {\n    func silenceWarning() {}\n}\n\n#if os(Linux)\nimport func Glibc.random\n\nfunc arc4random() -> UInt32 {\n    return UInt32(random())\n}\n\nextension XCTestExpectation {\n    func fulfill() {\n        fulfill(#file, line: #line)\n    }\n}\n\nextension XCTestCase {\n    func wait(for: [XCTestExpectation], timeout: TimeInterval, file: StaticString = #file, line: UInt = #line) {\n    #if !(swift(>=4.0) && !swift(>=4.1))\n        let line = Int(line)\n    #endif\n        waitForExpectations(timeout: timeout, file: file, line: line)\n    }\n}\n#endif\n"
  },
  {
    "path": "Tests/A+/2.1.2.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass Test212: XCTestCase {\n    func test() {\n        describe(\"2.1.2.1: When fulfilled, a promise: must not transition to any other state.\") {\n            testFulfilled { promise, expectation, _ in\n                promise.test(onFulfilled: expectation.fulfill, onRejected: { XCTFail() })\n            }\n\n            specify(\"trying to fulfill then immediately reject\") { d, expectation in\n                d.promise.test(onFulfilled: expectation.fulfill, onRejected: { XCTFail() })\n                d.fulfill()\n                d.reject(Error.dummy)\n            }\n\n            specify(\"trying to fulfill then reject, delayed\") { d, expectation in\n                d.promise.test(onFulfilled: expectation.fulfill, onRejected: { XCTFail() })\n                after(ticks: 1) {\n                    d.fulfill()\n                    d.reject(Error.dummy)\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/A+/2.1.3.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass Test213: XCTestCase {\n    func test() {\n        describe(\"2.1.3.1: When rejected, a promise: must not transition to any other state.\") {\n            testRejected { promise, expectation, _ in\n                promise.test(onFulfilled: { XCTFail() }, onRejected: expectation.fulfill)\n            }\n\n            specify(\"trying to reject then immediately fulfill\") { d, expectation in\n                d.promise.test(onFulfilled: { XCTFail() }, onRejected: expectation.fulfill)\n                d.reject(Error.dummy)\n                d.fulfill()\n            }\n\n            specify(\"trying to reject then fulfill, delayed\") { d, expectation in\n                d.promise.test(onFulfilled: { XCTFail() }, onRejected: expectation.fulfill)\n                after(ticks: 1) {\n                    d.reject(Error.dummy)\n                    d.fulfill()\n                }\n            }\n\n            specify(\"trying to reject immediately then fulfill delayed\") { d, expectation in\n                d.promise.test(onFulfilled: { XCTFail() }, onRejected: expectation.fulfill)\n                d.reject(Error.dummy)\n                after(ticks: 1) {\n                    d.fulfill()\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/A+/2.2.2.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass Test222: XCTestCase {\n    func test() {\n        describe(\"2.2.2: If `onFulfilled` is a function,\") {\n            describe(\"2.2.2.1: it must be called after `promise` is fulfilled, with `promise`’s fulfillment value as its first argument.\") {\n                testFulfilled { promise, expectation, sentinel in\n                    promise.done {\n                        XCTAssertEqual(sentinel, $0)\n                        expectation.fulfill()\n                    }.silenceWarning()\n                }\n            }\n\n            describe(\"2.2.2.2: it must not be called before `promise` is fulfilled\") {\n                specify(\"fulfilled after a delay\") { d, expectation in\n                    var called = false\n                    d.promise.done {\n                        called = true\n                        expectation.fulfill()\n                    }.silenceWarning()\n                    after(ticks: 5) {\n                        XCTAssertFalse(called)\n                        d.fulfill()\n                    }\n                }\n                specify(\"never fulfilled\") { d, expectation in\n                    d.promise.done{ XCTFail() }.silenceWarning()\n                    after(ticks: 1000, execute: expectation.fulfill)\n                }\n            }\n\n            describe(\"2.2.2.3: it must not be called more than once.\") {\n                specify(\"already-fulfilled\") { _, expectation in\n                    let ex = (expectation, mkex())\n                    Promise().done {\n                        ex.0.fulfill()\n                    }.silenceWarning()\n                    after(ticks: 1000) {\n                        ex.1.fulfill()\n                    }\n                }\n                specify(\"trying to fulfill a pending promise more than once, immediately\") { d, expectation in\n                    d.promise.done(expectation.fulfill).silenceWarning()\n                    d.fulfill()\n                    d.fulfill()\n                }\n                specify(\"trying to fulfill a pending promise more than once, delayed\") { d, expectation in\n                    d.promise.done(expectation.fulfill).silenceWarning()\n                    after(ticks: 5) {\n                        d.fulfill()\n                        d.fulfill()\n                    }\n                }\n                specify(\"trying to fulfill a pending promise more than once, immediately then delayed\") { d, expectation in\n                    let ex = (expectation, mkex())\n                    d.promise.done(ex.0.fulfill).silenceWarning()\n                    d.fulfill()\n                    after(ticks: 5) {\n                        d.fulfill()\n                    }\n                    after(ticks: 10, execute: ex.1.fulfill)\n                }\n                specify(\"when multiple `then` calls are made, spaced apart in time\") { d, expectation in\n                    let ex = (expectation, self.expectation(description: \"\"), self.expectation(description: \"\"), self.expectation(description: \"\"))\n\n                    do {\n                        d.promise.done(ex.0.fulfill).silenceWarning()\n                    }\n                    after(ticks: 5) {\n                        d.promise.done(ex.1.fulfill).silenceWarning()\n                    }\n                    after(ticks: 10) {\n                        d.promise.done(ex.2.fulfill).silenceWarning()\n                    }\n                    after(ticks: 15) {\n                        d.fulfill()\n                        ex.3.fulfill()\n                    }\n                }\n                specify(\"when `then` is interleaved with fulfillment\") { d, expectation in\n                    let ex = (expectation, self.expectation(description: \"\"), self)\n\n                    d.promise.done(ex.0.fulfill).silenceWarning()\n                    d.fulfill()\n                    d.promise.done(ex.1.fulfill).silenceWarning()\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/A+/2.2.3.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass Test223: XCTestCase {\n    func test() {\n        describe(\"2.2.3: If `onRejected` is a function,\") {\n            describe(\"2.2.3.1: it must be called after `promise` is rejected, with `promise`’s rejection reason as its first argument.\") {\n                testRejected { promise, expectation, sentinel in\n                    promise.catch { error in\n                        if case Error.sentinel(let value) = error {\n                            XCTAssertEqual(value, sentinel)\n                        } else {\n                            XCTFail()\n                        }\n                        expectation.fulfill()\n                    }\n                }\n            }\n            describe(\"2.2.3.2: it must not be called before `promise` is rejected\") {\n                specify(\"rejected after a delay\") { d, expectation in\n                    var called = false\n                    d.promise.catch { _ in\n                        called = true\n                        expectation.fulfill()\n                    }\n                    after(ticks: 1) {\n                        XCTAssertFalse(called)\n                        d.reject(Error.dummy)\n                    }\n                }\n                specify(\"never rejected\") { d, expectation in\n                    d.promise.catch { _ in XCTFail() }\n                    after(ticks: 1, execute: expectation.fulfill)\n                }\n            }\n            describe(\"2.2.3.3: it must not be called more than once.\") {\n                specify(\"already-rejected\") { d, expectation in\n                    var timesCalled = 0\n                    Promise<Int>(error: Error.dummy).catch { _ in\n                        XCTAssertEqual(++timesCalled, 1)\n                    }\n                    after(ticks: 2) {\n                        XCTAssertEqual(timesCalled, 1)\n                        expectation.fulfill()\n                    }\n                }\n                specify(\"trying to reject a pending promise more than once, immediately\") { d, expectation in\n                    d.promise.catch{_ in expectation.fulfill() }\n                    d.reject(Error.dummy)\n                    d.reject(Error.dummy)\n                }\n                specify(\"trying to reject a pending promise more than once, delayed\") { d, expectation in\n                    d.promise.catch{_ in expectation.fulfill() }\n                    after(ticks: 1) {\n                        d.reject(Error.dummy)\n                        d.reject(Error.dummy)\n                    }\n                }\n                specify(\"trying to reject a pending promise more than once, immediately then delayed\") { d, expectation in\n                    d.promise.catch{_ in expectation.fulfill() }\n                    d.reject(Error.dummy)\n                    after(ticks: 1) {\n                        d.reject(Error.dummy)\n                    }\n                }\n                specify(\"when multiple `then` calls are made, spaced apart in time\") { d, expectation in\n                    let mk = { self.expectation(description: \"\") }\n                    let ex = (expectation, mk(), mk(), mk())\n\n                    do {\n                        d.promise.catch{ _ in ex.0.fulfill() }\n                    }\n                    after(ticks: 1) {\n                        d.promise.catch{ _ in ex.1.fulfill() }\n                    }\n                    after(ticks: 2) {\n                        d.promise.catch{ _ in ex.2.fulfill() }\n                    }\n                    after(ticks: 3) {\n                        d.reject(Error.dummy)\n                        ex.3.fulfill()\n                    }\n                }\n                specify(\"when `then` is interleaved with rejection\") { d, expectation in\n                    let ex = (expectation, self.expectation(description: \"\"))\n                    d.promise.catch{ _ in ex.0.fulfill() }\n                    d.reject(Error.dummy)\n                    d.promise.catch{ _ in ex.1.fulfill() }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/A+/2.2.4.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass Test224: XCTestCase {\n    func test() {\n        describe(\"2.2.4: `onFulfilled` or `onRejected` must not be called until the execution context stack contains only platform code.\") {\n\n            describe(\"`then` returns before the promise becomes fulfilled or rejected\") {\n                testFulfilled { promise, expectation, dummy in\n                    var thenHasReturned = false\n                    promise.done { _ in\n                        XCTAssert(thenHasReturned)\n                        expectation.fulfill()\n                    }.silenceWarning()\n                    thenHasReturned = true\n                }\n                testRejected { promise, expectation, memo in\n                    var catchHasReturned = false\n                    promise.catch { _->() in\n                        XCTAssert(catchHasReturned)\n                        expectation.fulfill()\n                    }\n                    catchHasReturned = true\n                }\n\n            }\n\n            describe(\"Clean-stack execution ordering tests (fulfillment case)\") {\n                specify(\"when `onFulfilled` is added immediately before the promise is fulfilled\") { d, expectation in\n                    var onFulfilledCalled = false\n                    d.promise.done {\n                        onFulfilledCalled = true\n                        expectation.fulfill()\n                    }.silenceWarning()\n                    d.fulfill()\n                    XCTAssertFalse(onFulfilledCalled)\n                }\n                specify(\"when `onFulfilled` is added immediately after the promise is fulfilled\") { d, expectation in\n                    var onFulfilledCalled = false\n                    d.fulfill()\n                    d.promise.done {\n                        onFulfilledCalled = true\n                        expectation.fulfill()\n                    }.silenceWarning()\n                    XCTAssertFalse(onFulfilledCalled)\n                }\n                specify(\"when one `onFulfilled` is added inside another `onFulfilled`\") { _, expectation in\n                    var firstOnFulfilledFinished = false\n                    let promise = Promise()\n                    promise.done {\n                        promise.done {\n                            XCTAssertTrue(firstOnFulfilledFinished)\n                            expectation.fulfill()\n                        }.silenceWarning()\n                        firstOnFulfilledFinished = true\n                    }.silenceWarning()\n                }\n\n                specify(\"when `onFulfilled` is added inside an `onRejected`\") { _, expectation in\n                    let promise1 = Promise<Void>(error: Error.dummy)\n                    let promise2 = Promise()\n                    var firstOnRejectedFinished = false\n\n                    promise1.catch { _ in\n                        promise2.done {\n                            XCTAssertTrue(firstOnRejectedFinished)\n                            expectation.fulfill()\n                        }.silenceWarning()\n                        firstOnRejectedFinished = true\n                    }\n                }\n                \n                specify(\"when the promise is fulfilled asynchronously\") { d, expectation in\n                    var firstStackFinished = false\n\n                    after(ticks: 1) {\n                        d.fulfill()\n                        firstStackFinished = true\n                    }\n\n                    d.promise.done {\n                        XCTAssertTrue(firstStackFinished)\n                        expectation.fulfill()\n                    }.silenceWarning()\n                }\n            }\n\n            describe(\"Clean-stack execution ordering tests (rejection case)\") {\n                specify(\"when `onRejected` is added immediately before the promise is rejected\") { d, expectation in\n                    var onRejectedCalled = false\n                    d.promise.catch { _ in\n                        onRejectedCalled = true\n                        expectation.fulfill()\n                    }\n                    d.reject(Error.dummy)\n                    XCTAssertFalse(onRejectedCalled)\n                }\n                specify(\"when `onRejected` is added immediately after the promise is rejected\") { d, expectation in\n                    var onRejectedCalled = false\n                    d.reject(Error.dummy)\n                    d.promise.catch { _ in\n                        onRejectedCalled = true\n                        expectation.fulfill()\n                    }\n                    XCTAssertFalse(onRejectedCalled)\n                }\n                specify(\"when `onRejected` is added inside an `onFulfilled`\") { d, expectation in\n                    let promise1 = Promise()\n                    let promise2 = Promise<Void>(error: Error.dummy)\n                    var firstOnFulfilledFinished = false\n\n                    promise1.done { _ in\n                        promise2.catch { _ in\n                            XCTAssertTrue(firstOnFulfilledFinished)\n                            expectation.fulfill()\n                        }\n                        firstOnFulfilledFinished = true\n                    }.silenceWarning()\n                }\n                specify(\"when one `onRejected` is added inside another `onRejected`\") { d, expectation in\n                    let promise = Promise<Void>(error: Error.dummy)\n                    var firstOnRejectedFinished = false;\n\n                    promise.catch { _ in\n                        promise.catch { _ in\n                            XCTAssertTrue(firstOnRejectedFinished)\n                            expectation.fulfill()\n                        }\n                        firstOnRejectedFinished = true\n                    }\n                }\n                specify(\"when the promise is rejected asynchronously\") { d, expectation in\n                    var firstStackFinished = false\n                    after(ticks: 1) {\n                        d.reject(Error.dummy)\n                        firstStackFinished = true\n                    }\n                    d.promise.catch { _ in\n                        XCTAssertTrue(firstStackFinished)\n                        expectation.fulfill()\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/A+/2.2.6.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass Test226: XCTestCase {\n    func test() {\n        describe(\"2.2.6: `then` may be called multiple times on the same promise.\") {\n            describe(\"2.2.6.1: If/when `promise` is fulfilled, all respective `onFulfilled` callbacks must execute in the order of their originating calls to `then`.\") {\n                describe(\"multiple boring fulfillment handlers\") {\n                    testFulfilled(withExpectationCount: 4) { promise, exes, sentinel -> Void in\n                        var orderValidator = 0\n                        promise.done {\n                            XCTAssertEqual($0, sentinel)\n                            XCTAssertEqual(++orderValidator, 1)\n                            exes[0].fulfill()\n                        }.silenceWarning()\n                        promise.catch { _ in XCTFail() }\n                        promise.done {\n                            XCTAssertEqual($0, sentinel)\n                            XCTAssertEqual(++orderValidator, 2)\n                            exes[1].fulfill()\n                        }.silenceWarning()\n                        promise.catch { _ in XCTFail() }\n                        promise.done {\n                            XCTAssertEqual($0, sentinel)\n                            XCTAssertEqual(++orderValidator, 3)\n                            exes[2].fulfill()\n                        }.silenceWarning()\n                        promise.catch { _ in XCTFail() }\n                        promise.done {\n                            XCTAssertEqual($0, sentinel)\n                            XCTAssertEqual(++orderValidator, 4)\n                            exes[3].fulfill()\n                        }.silenceWarning()\n                    }\n                }\n                describe(\"multiple fulfillment handlers, one of which throws\") {\n                    testFulfilled(withExpectationCount: 4) { promise, exes, sentinel in\n                        var orderValidator = 0\n                        promise.done {\n                            XCTAssertEqual($0, sentinel)\n                            XCTAssertEqual(++orderValidator, 1)\n                            exes[0].fulfill()\n                        }.silenceWarning()\n                        promise.catch { _ in XCTFail() }\n                        promise.done {\n                            XCTAssertEqual($0, sentinel)\n                            XCTAssertEqual(++orderValidator, 2)\n                            exes[1].fulfill()\n                        }.silenceWarning()\n                        promise.catch { _ in XCTFail() }\n                        promise.done {\n                            XCTAssertEqual($0, sentinel)\n                            XCTAssertEqual(++orderValidator, 3)\n                            exes[2].fulfill()\n                            throw Error.dummy\n                        }.silenceWarning()\n                        promise.catch { value in XCTFail() }\n                        promise.done {\n                            XCTAssertEqual($0, sentinel)\n                            XCTAssertEqual(++orderValidator, 4)\n                            exes[3].fulfill()\n                        }.silenceWarning()\n                    }\n                }\n                describe(\"results in multiple branching chains with their own fulfillment values\") {\n                    testFulfilled(withExpectationCount: 3) { promise, exes, memo in\n                        let sentinel1 = 671\n                        let sentinel2: UInt32 = 672\n                        let sentinel3 = 673\n\n                        promise.map { _ in\n                            return sentinel1\n                        }.done { value in\n                            XCTAssertEqual(sentinel1, value)\n                            exes[0].fulfill()\n                        }.silenceWarning()\n\n                        promise.done { _ in\n                            throw Error.sentinel(sentinel2)\n                        }.catch { err in\n                            switch err {\n                            case Error.sentinel(let err) where err == sentinel2:\n                                break\n                            default:\n                                XCTFail()\n                            }\n                            exes[1].fulfill()\n                        }\n\n                        promise.map { _ in\n                            sentinel3\n                        }.done {\n                            XCTAssertEqual($0, sentinel3)\n                            exes[2].fulfill()\n                        }.silenceWarning()\n                    }\n                }\n                describe(\"`onFulfilled` handlers are called in the original order\") {\n                    testFulfilled(withExpectationCount: 3) { promise, exes, memo in\n                        var orderValidator = 0\n\n                        promise.done { _ in\n                            XCTAssertEqual(++orderValidator, 1)\n                            exes[0].fulfill()\n                        }.silenceWarning()\n                        promise.done { _ in\n                            XCTAssertEqual(++orderValidator, 2)\n                            exes[1].fulfill()\n                        }.silenceWarning()\n                        promise.done { _ in\n                            XCTAssertEqual(++orderValidator, 3)\n                            exes[2].fulfill()\n                        }.silenceWarning()\n                    }\n                }\n                describe(\"even when one handler is added inside another handler\") {\n                    testFulfilled(withExpectationCount: 3) { promise, exes, memo in\n                        var x = 0\n                        promise.done { _ in\n                            XCTAssertEqual(x, 0)\n                            x += 1\n                            exes[0].fulfill()\n                            promise.done { _ in\n                                XCTAssertEqual(x, 2)\n                                x += 1\n                                exes[1].fulfill()\n                            }.silenceWarning()\n                        }.silenceWarning()\n                        promise.done { _ in\n                            XCTAssertEqual(x, 1)\n                            x += 1\n                            exes[2].fulfill()\n                        }.silenceWarning()\n                    }\n                }\n            }\n            describe(\"2.2.6.2: If/when `promise` is rejected, all respective `onRejected` callbacks must execute in the order of their originating calls to `then`.\") {\n                describe(\"multiple boring rejection handlers\") {\n                    testRejected(withExpectationCount: 4) { promise, exes, sentinel in\n                        var ticket = 0\n\n                        promise.catch { err in\n                            guard case Error.sentinel(let x) = err, x == sentinel else { return XCTFail() }\n                            XCTAssertEqual(++ticket, 1)\n                            exes[0].fulfill()\n                        }\n                        promise.done { _ in XCTFail() }.silenceWarning()\n                        promise.catch { err in\n                            guard case Error.sentinel(let x) = err, x == sentinel else { return XCTFail() }\n                            XCTAssertEqual(++ticket, 2)\n                            exes[1].fulfill()\n                        }\n                        promise.done { _ in XCTFail() }.silenceWarning()\n                        promise.catch { err in\n                            guard case Error.sentinel(let x) = err, x == sentinel else { return XCTFail() }\n                            XCTAssertEqual(++ticket, 3)\n                            exes[2].fulfill()\n                        }\n                        promise.done { _ in XCTFail() }.silenceWarning()\n                        promise.catch { err in\n                            guard case Error.sentinel(let x) = err, x == sentinel else { return XCTFail() }\n                            XCTAssertEqual(++ticket, 4)\n                            exes[3].fulfill()\n                        }\n                    }\n                }\n                describe(\"multiple rejection handlers, one of which throws\") {\n                    testRejected(withExpectationCount: 4) { promise, exes, sentinel in\n                        var orderValidator = 0\n\n                        promise.catch { err in\n                            guard case Error.sentinel(let x) = err, x == sentinel else { return XCTFail() }\n                            XCTAssertEqual(++orderValidator, 1)\n                            exes[0].fulfill()\n                        }\n                        promise.done { _ in XCTFail() }.silenceWarning()\n                        promise.catch { err in\n                            guard case Error.sentinel(let x) = err, x == sentinel else { return XCTFail() }\n                            XCTAssertEqual(++orderValidator, 2)\n                            exes[1].fulfill()\n                        }\n                        promise.done { _ in XCTFail() }.silenceWarning()\n                        promise.recover { err -> Promise<UInt32> in\n                            if case Error.sentinel(let x) = err {\n                                XCTAssertEqual(x, sentinel)\n                            } else {\n                                XCTFail()\n                            }\n                            XCTAssertEqual(++orderValidator, 3)\n                            exes[2].fulfill()\n                            throw Error.dummy\n                        }.silenceWarning()\n                        promise.done { _ in XCTFail() }.silenceWarning()\n                        promise.catch { err in\n                            guard case Error.sentinel(let x) = err, x == sentinel else { return XCTFail() }\n                            XCTAssertEqual(++orderValidator, 4)\n                            exes[3].fulfill()\n                        }\n                    }\n                }\n                describe(\"results in multiple branching chains with their own fulfillment values\") {\n                    testRejected(withExpectationCount: 3) { promise, exes, memo in\n                        let sentinel1 = arc4random()\n                        let sentinel2 = arc4random()\n                        let sentinel3 = arc4random()\n\n                        promise.recover { _ in\n                            return .value(sentinel1)\n                        }.done { value in\n                            XCTAssertEqual(sentinel1, value)\n                            exes[0].fulfill()\n                        }\n\n                        promise.recover { _ -> Promise<UInt32> in\n                            throw Error.sentinel(sentinel2)\n                        }.catch { err in\n                            if case Error.sentinel(let x) = err, x == sentinel2 {\n                                exes[1].fulfill()\n                            }\n                        }\n                        \n                        promise.recover { _ in\n                            .value(sentinel3)\n                        }.done { value in\n                            XCTAssertEqual(value, sentinel3)\n                            exes[2].fulfill()\n                        }\n                    }\n                }\n                describe(\"`onRejected` handlers are called in the original order\") {\n                    testRejected(withExpectationCount: 3) { promise, exes, memo in\n                        var x = 0\n\n                        promise.catch { _ in\n                            XCTAssertEqual(x, 0)\n                            x += 1\n                            exes[0].fulfill()\n                        }\n                        promise.catch { _ in\n                            XCTAssertEqual(x, 1)\n                            x += 1\n                            exes[1].fulfill()\n                        }\n                        promise.catch { _ in\n                            XCTAssertEqual(x, 2)\n                            x += 1\n                            exes[2].fulfill()\n                        }\n                    }\n                }\n                describe(\"even when one handler is added inside another handler\") {\n                    testRejected(withExpectationCount: 3) { promise, exes, memo in\n                        var x = 0\n\n                        promise.catch { _ in\n                            XCTAssertEqual(x, 0)\n                            x += 1\n                            exes[0].fulfill()\n                            promise.catch { _ in\n                                XCTAssertEqual(x, 2)\n                                x += 1\n                                exes[1].fulfill()\n                            }\n                        }\n                        promise.catch { _ in\n                            XCTAssertEqual(x, 1)\n                            x += 1\n                            exes[2].fulfill()\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/A+/2.2.7.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass Test227: XCTestCase {\n    func test() {\n        describe(\"2.2.7: `then` must return a promise: `promise2 = promise1.then(onFulfilled, onRejected)\") {\n            describe(\"2.2.7.2: If either `onFulfilled` or `onRejected` throws an exception `e`, `promise2` must be rejected with `e` as the reason.\") {\n\n                testFulfilled { promise1, expectation, _ in\n                    let sentinel = arc4random()\n                    let promise2 = promise1.done { _ in throw Error.sentinel(sentinel) }\n\n                    promise2.catch {\n                        if case Error.sentinel(let x) = $0, x == sentinel {\n                            expectation.fulfill()\n                        }\n                    }\n                }\n\n                testRejected { promise1, expectation, _ in\n                    let sentinel = arc4random()\n                    let promise2 = promise1.recover { _ -> Promise<UInt32> in throw Error.sentinel(sentinel) }\n\n                    promise2.catch { error in\n                        if case Error.sentinel(let x) = error, x == sentinel {\n                            expectation.fulfill()\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/A+/2.3.1.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass Test231: XCTestCase {\n    func test() {\n        describe(\"2.3.1: If `promise` and `x` refer to the same object, reject `promise` with a `TypeError' as the reason.\") {\n            specify(\"via return from a fulfilled promise\") { d, expectation in\n                var promise: Promise<Void>!\n                promise = Promise().then { () -> Promise<Void> in\n                    return promise\n                }\n                promise.catch { err in\n                    if case PMKError.returnedSelf = err {\n                        expectation.fulfill()\n                    }\n                }\n            }\n            specify(\"via return from a rejected promise\") { d, expectation in\n                var promise: Promise<Void>!\n                promise = Promise<Void>(error: Error.dummy).recover { _ -> Promise<Void> in\n                    return promise\n                }\n                promise.catch { err in\n                    if case PMKError.returnedSelf = err {\n                        expectation.fulfill()\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/A+/2.3.2.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass Test232: XCTestCase {\n    func test() {\n        describe(\"2.3.2: If `x` is a promise, adopt its state\") {\n            describe(\"2.3.2.1: If `x` is pending, `promise` must remain pending until `x` is fulfilled or rejected.\") {\n\n                func xFactory() -> Promise<UInt32> {\n                    return Promise.pending().promise\n                }\n\n                testPromiseResolution(factory: xFactory) { promise, expectation in\n                    var wasFulfilled = false;\n                    var wasRejected = false;\n\n                    promise.test(onFulfilled: { wasFulfilled = true }, onRejected: { wasRejected = true })\n\n                    after(ticks: 4) {\n                        XCTAssertFalse(wasFulfilled)\n                        XCTAssertFalse(wasRejected)\n                        expectation.fulfill()\n                    }\n                }\n            }\n\n            describe(\"2.3.2.2: If/when `x` is fulfilled, fulfill `promise` with the same value.\") {\n                describe(\"`x` is already-fulfilled\") {\n                    let sentinel = arc4random()\n\n                    func xFactory() -> Promise<UInt32> {\n                        return .value(sentinel)\n                    }\n\n                    testPromiseResolution(factory: xFactory) { promise, expectation in\n                        promise.done {\n                            XCTAssertEqual($0, sentinel)\n                            expectation.fulfill()\n                        }.silenceWarning()\n                    }\n                }\n                describe(\"`x` is eventually-fulfilled\") {\n                    let sentinel = arc4random()\n\n                    func xFactory() -> Promise<UInt32> {\n                        return Promise { seal in\n                            after(ticks: 2) {\n                                seal.fulfill(sentinel)\n                            }\n                        }\n                    }\n\n                    testPromiseResolution(factory: xFactory) { promise, expectation in\n                        promise.done {\n                            XCTAssertEqual($0, sentinel)\n                            expectation.fulfill()\n                        }.silenceWarning()\n                    }\n                }\n            }\n\n            describe(\"2.3.2.3: If/when `x` is rejected, reject `promise` with the same reason.\") {\n                describe(\"`x` is already-rejected\") {\n                    let sentinel = arc4random()\n\n                    func xFactory() -> Promise<UInt32> {\n                        return Promise(error: Error.sentinel(sentinel))\n                    }\n\n                    testPromiseResolution(factory: xFactory) { promise, expectation in\n                        promise.catch { err in\n                            if case Error.sentinel(let value) = err, value == sentinel {\n                                expectation.fulfill()\n                            }\n                        }\n                    }\n                }\n                describe(\"`x` is eventually-rejected\") {\n                    let sentinel = arc4random()\n\n                    func xFactory() -> Promise<UInt32> {\n                        return Promise { seal in\n                            after(ticks: 2) {\n                                seal.reject(Error.sentinel(sentinel))\n                            }\n                        }\n                    }\n\n                    testPromiseResolution(factory: xFactory) { promise, expectation in\n                        promise.catch { err in\n                            if case Error.sentinel(let value) = err, value == sentinel {\n                                expectation.fulfill()\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n\n/////////////////////////////////////////////////////////////////////////\n\nextension Test232 {\n    fileprivate func testPromiseResolution(factory: @escaping () -> Promise<UInt32>, line: UInt = #line, test: (Promise<UInt32>, XCTestExpectation) -> Void) {\n        specify(\"via return from a fulfilled promise\", file: #file, line: line) { d, expectation in\n            let promise = Promise.value(arc4random()).then { _ in factory() }\n            test(promise, expectation)\n        }\n        specify(\"via return from a rejected promise\", file: #file, line: line) { d, expectation in\n            let promise: Promise<UInt32> = Promise(error: Error.dummy).recover { _ in factory() }\n            test(promise, expectation)\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/A+/2.3.4.swift",
    "content": "import PromiseKit\nimport XCTest\n\n\nclass Test234: XCTestCase {\n    func test() {\n        describe(\"2.3.4: If `x` is not an object or function, fulfill `promise` with `x`\") {\n            testFulfilled { promise, exception, _ in\n                promise.map { value -> UInt32 in\n                    return 1\n                }.done { value in\n                    XCTAssertEqual(value, 1)\n                    exception.fulfill()\n                }.silenceWarning()\n            }\n            testRejected { promise, expectation, _ in\n                promise.recover { _ -> Promise<UInt32> in\n                    return .value(UInt32(1))\n                }.done { value in\n                    XCTAssertEqual(value, 1)\n                    expectation.fulfill()\n                }.silenceWarning()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/A+/README.md",
    "content": "Resources\n=========\n* https://github.com/promises-aplus/promises-tests\n\n\nSkipped\n=======\n* 2.3.3: Otherwise, if x is an object or function.\n  This spec is a NOOP for Swift:\n  - We have decided not to interact with other Promises A+ implementations\n  - functions cannot have properties\n* 2.3.3.4: If then is not a function, fulfill promise with x.\n  - See: The 2.3.4 suite.\n"
  },
  {
    "path": "Tests/A+/XCTestManifests.swift",
    "content": "#if !canImport(ObjectiveC)\nimport XCTest\n\n#if os(Android)\nextension XCTestExpectation {\n    func fulfill() {\n        fulfill(#file, line: #line)\n    }\n}\n#endif\n\nextension Test212 {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__Test212 = [\n        (\"test\", test),\n    ]\n}\n\nextension Test213 {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__Test213 = [\n        (\"test\", test),\n    ]\n}\n\nextension Test222 {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__Test222 = [\n        (\"test\", test),\n    ]\n}\n\nextension Test223 {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__Test223 = [\n        (\"test\", test),\n    ]\n}\n\nextension Test224 {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__Test224 = [\n        (\"test\", test),\n    ]\n}\n\nextension Test226 {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__Test226 = [\n        (\"test\", test),\n    ]\n}\n\nextension Test227 {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__Test227 = [\n        (\"test\", test),\n    ]\n}\n\nextension Test231 {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__Test231 = [\n        (\"test\", test),\n    ]\n}\n\nextension Test232 {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__Test232 = [\n        (\"test\", test),\n    ]\n}\n\nextension Test234 {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__Test234 = [\n        (\"test\", test),\n    ]\n}\n\npublic func __allTests() -> [XCTestCaseEntry] {\n    return [\n        testCase(Test212.__allTests__Test212),\n        testCase(Test213.__allTests__Test213),\n        testCase(Test222.__allTests__Test222),\n        testCase(Test223.__allTests__Test223),\n        testCase(Test224.__allTests__Test224),\n        testCase(Test226.__allTests__Test226),\n        testCase(Test227.__allTests__Test227),\n        testCase(Test231.__allTests__Test231),\n        testCase(Test232.__allTests__Test232),\n        testCase(Test234.__allTests__Test234),\n    ]\n}\n#endif\n"
  },
  {
    "path": "Tests/Bridging/BridgingTests.m",
    "content": "@import PromiseKit;\n@import XCTest;\n#import \"Infrastructure.h\"\n\n\n@interface BridgingTests: XCTestCase @end @implementation BridgingTests\n\n- (void)testChainAnyPromiseFromSwiftCode {\n    XCTestExpectation *ex = [self expectationWithDescription:@\"\"];\n    AnyPromise *promise = PMKAfter(0.02);\n    for (int x = 0; x < 100; ++x) {\n        promise = promise.then(^{\n            return [[[PromiseBridgeHelper alloc] init] bridge1];\n        });\n    }\n    promise.then(^{\n        [ex fulfill];\n    });\n    [self waitForExpectationsWithTimeout:20 handler:nil];\n}\n\n- (void)test626 {\n    XCTestExpectation *ex = [self expectationWithDescription:@\"\"];\n\n    testCase626().then(^{\n        XCTFail();\n    }).ensure(^{\n        [ex fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:20 handler:nil];\n}\n\n@end\n"
  },
  {
    "path": "Tests/Bridging/BridgingTests.swift",
    "content": "import Foundation\nimport PromiseKit\nimport XCTest\n\nclass BridgingTests: XCTestCase {\n\n    func testCanBridgeAnyObject() {\n        let sentinel = NSURLRequest()\n        let p = Promise.value(sentinel)\n        let ap = AnyPromise(p)\n\n        XCTAssertEqual(ap.value(forKey: \"value\") as? NSURLRequest, sentinel)\n    }\n\n    func testCanBridgeOptional() {\n        let sentinel: NSURLRequest? = NSURLRequest()\n        let p = Promise.value(sentinel)\n        let ap = AnyPromise(p)\n\n        XCTAssertEqual(ap.value(forKey: \"value\") as? NSURLRequest, sentinel)\n    }\n\n    func testCanBridgeSwiftArray() {\n        let sentinel = [NSString(), NSString(), NSString()]\n        let p = Promise.value(sentinel)\n        let ap = AnyPromise(p)\n\n        guard let foo = ap.value(forKey: \"value\") as? [NSString] else { return XCTFail() }\n        XCTAssertEqual(foo, sentinel)\n    }\n\n    func testCanBridgeSwiftDictionary() {\n        let sentinel = [NSString(): NSString()]\n        let p = Promise.value(sentinel)\n        let ap = AnyPromise(p)\n\n        guard let foo = ap.value(forKey: \"value\") as? [NSString: NSString] else { return XCTFail() }\n        XCTAssertEqual(foo, sentinel)\n    }\n\n    func testCanBridgeInt() {\n        let sentinel = 3\n        let p = Promise.value(sentinel)\n        let ap = AnyPromise(p)\n        XCTAssertEqual(ap.value(forKey: \"value\") as? Int, sentinel)\n    }\n\n    func testCanBridgeString() {\n        let sentinel = \"a\"\n        let p = Promise.value(sentinel)\n        let ap = AnyPromise(p)\n        XCTAssertEqual(ap.value(forKey: \"value\") as? String, sentinel)\n    }\n\n    func testCanBridgeBool() {\n        let sentinel = true\n        let p = Promise.value(sentinel)\n        let ap = AnyPromise(p)\n        XCTAssertEqual(ap.value(forKey: \"value\") as? Bool, sentinel)\n    }\n\n    func testCanChainOffAnyPromiseFromObjC() {\n        let ex = expectation(description: \"\")\n\n        firstly {\n            .value(1)\n        }.then { _ -> AnyPromise in\n            return PromiseBridgeHelper().value(forKey: \"bridge2\") as! AnyPromise\n        }.done { value in\n            XCTAssertEqual(123, value as? Int)\n            ex.fulfill()\n        }.silenceWarning()\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testCanThenOffAnyPromise() {\n        let ex = expectation(description: \"\")\n\n        PMKDummyAnyPromise_YES().then { obj -> Promise<Void> in\n            if let value = obj as? NSNumber {\n                XCTAssertEqual(value, NSNumber(value: true))\n                ex.fulfill()\n            }\n            return Promise()\n        }.silenceWarning()\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testCanThenOffManifoldAnyPromise() {\n        let ex = expectation(description: \"\")\n\n        PMKDummyAnyPromise_Manifold().then { obj -> Promise<Void> in\n            defer { ex.fulfill() }\n            XCTAssertEqual(obj as? NSNumber, NSNumber(value: true), \"\\(obj ?? \"nil\") is not @YES\")\n            return Promise()\n        }.silenceWarning()\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testCanAlwaysOffAnyPromise() {\n        let ex = expectation(description: \"\")\n\n        PMKDummyAnyPromise_YES().then { obj -> Promise<Void>  in\n            ex.fulfill()\n            return Promise()\n        }.silenceWarning()\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testCanCatchOffAnyPromise() {\n        let ex = expectation(description: \"\")\n        PMKDummyAnyPromise_Error().catch { err in\n            ex.fulfill()\n        }\n        waitForExpectations(timeout: 1)\n    }\n\n    func testAsPromise() {\n    #if swift(>=3.1)\n        XCTAssertTrue(Promise(PMKDummyAnyPromise_Error()).isRejected)\n        XCTAssertEqual(Promise(PMKDummyAnyPromise_YES()).value as? NSNumber, NSNumber(value: true))\n    #else\n        XCTAssertTrue(PMKDummyAnyPromise_Error().asPromise().isRejected)\n        XCTAssertEqual(PMKDummyAnyPromise_YES().asPromise().value as? NSNumber, NSNumber(value: true))\n    #endif\n    }\n\n    func testFirstlyReturningAnyPromiseSuccess() {\n        let ex = expectation(description: \"\")\n        firstly {\n            PMKDummyAnyPromise_Error()\n        }.catch { error in\n            ex.fulfill()\n        }\n        waitForExpectations(timeout: 1)\n    }\n\n    func testFirstlyReturningAnyPromiseError() {\n        let ex = expectation(description: \"\")\n        firstly {\n            PMKDummyAnyPromise_YES()\n        }.done { _ in\n            ex.fulfill()\n        }.silenceWarning()\n        waitForExpectations(timeout: 1)\n    }\n\n    func test1() {\n        let ex = expectation(description: \"\")\n\n        // AnyPromise.then { return x }\n\n        let input = after(seconds: 0).map{ 1 }\n\n        AnyPromise(input).then { obj -> Promise<Int> in\n            XCTAssertEqual(obj as? Int, 1)\n            return .value(2)\n        }.done { value in\n            XCTAssertEqual(value, 2)\n            ex.fulfill()\n        }.silenceWarning()\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func test2() {\n        let ex = expectation(description: \"\")\n\n        // AnyPromise.then { return AnyPromise }\n\n        let input = after(seconds: 0).map{ 1 }\n\n        AnyPromise(input).then { obj -> AnyPromise in\n            XCTAssertEqual(obj as? Int, 1)\n            return AnyPromise(after(seconds: 0).map{ 2 })\n        }.done { obj in\n            XCTAssertEqual(obj as? Int, 2)\n            ex.fulfill()\n        }.silenceWarning()\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func test3() {\n        let ex = expectation(description: \"\")\n\n        // AnyPromise.then { return Promise<Int> }\n\n        let input = after(seconds: 0).map{ 1 }\n\n        AnyPromise(input).then { obj -> Promise<Int> in\n            XCTAssertEqual(obj as? Int, 1)\n            return after(seconds: 0).map{ 2 }\n        }.done { value in\n            XCTAssertEqual(value, 2)\n            ex.fulfill()\n        }.silenceWarning()\n\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n\n    // can return AnyPromise (that fulfills) in then handler\n    func test4() {\n        let ex = expectation(description: \"\")\n        Promise.value(1).then { _ -> AnyPromise in\n            return AnyPromise(after(seconds: 0).map{ 1 })\n        }.done { x in\n            XCTAssertEqual(x as? Int, 1)\n            ex.fulfill()\n        }.silenceWarning()\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n    // can return AnyPromise (that rejects) in then handler\n    func test5() {\n        let ex = expectation(description: \"\")\n\n        Promise.value(1).then { _ -> AnyPromise in\n            let promise = after(.milliseconds(100)).done{ throw Error.dummy }\n            return AnyPromise(promise)\n        }.catch { err in\n            ex.fulfill()\n        }\n        waitForExpectations(timeout: 1)\n    }\n\n    func testStandardSwiftBridgeIsUnambiguous() {\n        let p = Promise.value(1)\n        let q = Promise(p)\n\n        XCTAssertEqual(p.value, q.value)\n    }\n\n    /// testing NSError to Error for cancelledError types\n    func testErrorCancellationBridging() {\n        let ex = expectation(description: \"\")\n\n        let p = Promise().done {\n            throw LocalError.cancel as NSError\n        }\n        p.catch { _ in\n            XCTFail()\n        }\n        p.catch(policy: .allErrors) {\n            XCTAssertTrue($0.isCancelled)\n            ex.fulfill()\n        }\n        waitForExpectations(timeout: 1)\n\n        // here we verify that Swift’s NSError bridging works as advertised\n\n        XCTAssertTrue(LocalError.cancel.isCancelled)\n        XCTAssertTrue((LocalError.cancel as NSError).isCancelled)\n    }\n}\n\nprivate enum Error: Swift.Error {\n    case dummy\n}\n\nextension Promise {\n    func silenceWarning() {}\n}\n\nprivate enum LocalError: CancellableError {\n    case notCancel\n    case cancel\n\n    var isCancelled: Bool {\n        switch self {\n        case .notCancel: return false\n        case .cancel: return true\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/Bridging/Infrastructure.h",
    "content": "@import Foundation;\n@class AnyPromise;\n\nAnyPromise *PMKDummyAnyPromise_YES(void);\nAnyPromise *PMKDummyAnyPromise_Manifold(void);\nAnyPromise *PMKDummyAnyPromise_Error(void);\n\n__attribute__((objc_runtime_name(\"PMKPromiseBridgeHelper\")))\n__attribute__((objc_subclassing_restricted))\n@interface PromiseBridgeHelper: NSObject\n- (AnyPromise *)bridge1;\n@end\n\nAnyPromise *testCase626(void);\n"
  },
  {
    "path": "Tests/Bridging/Infrastructure.m",
    "content": "@import Foundation;\n@import PromiseKit;\n#import \"Infrastructure.h\"\n\nAnyPromise *PMKDummyAnyPromise_YES(void) {\n    return [AnyPromise promiseWithValue:@YES];\n}\n\nAnyPromise *PMKDummyAnyPromise_Manifold(void) {\n    return [AnyPromise promiseWithValue:PMKManifold(@YES, @NO, @NO)];\n}\n\nAnyPromise *PMKDummyAnyPromise_Error(void) {\n    return [AnyPromise promiseWithValue:[NSError errorWithDomain:@\"a\" code:1 userInfo:nil]];\n}\n\n@implementation PromiseBridgeHelper (objc)\n\n- (AnyPromise *)bridge2 {\n    return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{\n            resolve(@123);\n        });\n    }];\n}\n\n@end\n\n#import \"PMKBridgeTests-Swift.h\"\n\nAnyPromise *testCase626(void) {\n    return PMKWhen(@[[TestPromise626 promise], [TestPromise626 promise]]).then(^(id value){\n        NSLog(@\"Success: %@\", value);\n    }).catch(^(NSError *error) {\n        NSLog(@\"Error: %@\", error);\n        @throw error;\n    });\n}\n"
  },
  {
    "path": "Tests/Bridging/Infrastructure.swift",
    "content": "import PromiseKit\n\n// for BridgingTests.m\n@objc(PMKPromiseBridgeHelper) class PromiseBridgeHelper: NSObject {\n    @objc func bridge1() -> AnyPromise {\n        let p = after(.milliseconds(10))\n        return AnyPromise(p)\n    }\n}\n\nenum MyError: Error {\n    case PromiseError\n}\n\n@objc class TestPromise626: NSObject {\n\n    @objc class func promise() -> AnyPromise {\n        let promise: Promise<String> = Promise { seal in\n            seal.reject(MyError.PromiseError)\n        }\n\n        return AnyPromise(promise)\n    }\n}\n"
  },
  {
    "path": "Tests/CoreObjC/AnyPromiseTests.m",
    "content": "@import PromiseKit;\n@import XCTest;\n#import \"Infrastructure.h\"\n#define PMKTestErrorDomain @\"PMKTestErrorDomain\"\n\nstatic inline NSError *dummyWithCode(NSInteger code) {\n    return [NSError errorWithDomain:PMKTestErrorDomain code:rand() userInfo:@{NSLocalizedDescriptionKey: @(code).stringValue}];\n}\n\nstatic inline NSError *dummy(void) {\n    return dummyWithCode(rand());\n}\n\nstatic inline AnyPromise *rejectLater(void) {\n    return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{\n            dispatch_async(dispatch_get_main_queue(), ^{\n                resolve(dummy());\n            });\n        });\n    }];\n}\n\nstatic inline AnyPromise *fulfillLater(void) {\n    return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        dispatch_async(dispatch_get_global_queue(QOS_CLASS_UNSPECIFIED, 0), ^{\n            resolve(@1);\n        });\n    }];\n}\n\n\n\n@interface AnyPromiseTestSuite : XCTestCase @end @implementation AnyPromiseTestSuite\n\n- (void)test_01_resolve {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    AnyPromise *promise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(@1);\n    }];\n    promise.then(^(NSNumber *o){\n        [ex1 fulfill];\n        XCTAssertEqual(o.intValue, 1);\n    });\n    promise.catch(^{\n        XCTFail();\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_02_reject {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    AnyPromise *promise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(dummyWithCode(2));\n    }];\n    promise.then(^{\n        XCTFail();\n    });\n    promise.catch(^(NSError *error){\n        XCTAssertEqualObjects(error.localizedDescription, @\"2\");\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_03_return_error {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    AnyPromise *promise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(@2);\n    }];\n    promise.then(^{\n        return [NSError errorWithDomain:@\"a\" code:3 userInfo:nil];\n    }).catch(^(NSError *e){\n        [ex1 fulfill];\n        XCTAssertEqual(3, e.code);\n    });\n    promise.catch(^{\n        XCTFail();\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_04_return_error_doesnt_compromise_result {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    AnyPromise *promise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(@4);\n    }].then(^{\n        return dummy();\n    });\n    promise.then(^{\n        XCTFail();\n    });\n    promise.catch(^{\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_05_throw_and_bubble {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(@5);\n    }].then(^(id ii){\n        XCTAssertEqual(5, [ii intValue]);\n        return [NSError errorWithDomain:@\"a\" code:[ii intValue] userInfo:nil];\n    }).catch(^(NSError *e){\n        XCTAssertEqual(e.code, 5);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_05_throw_and_bubble_more {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(@5);\n    }].then(^{\n        return dummy();\n    }).then(^{\n        //NOOP\n    }).catch(^(NSError *e){\n        [ex1 fulfill];\n        XCTAssertEqualObjects(e.domain, PMKTestErrorDomain);\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_06_return_error {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(@5);\n    }].then(^{\n        return dummy();\n    }).catch(^{\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_07_can_then_resolved {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(@1);\n    }].then(^(id o){\n        [ex1 fulfill];\n        XCTAssertEqualObjects(@1, o);\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_07a_can_fail_rejected {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(dummyWithCode(1));\n    }].catch(^(NSError *e){\n        [ex1 fulfill];\n        XCTAssertEqualObjects(@\"1\", e.localizedDescription);\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_09_async {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    __block int x = 0;\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(@1);\n    }].then(^{\n        XCTAssertEqual(x, 0);\n        x++;\n    }).then(^{\n        XCTAssertEqual(x, 1);\n        x++;\n    }).then(^{\n        XCTAssertEqual(x, 2);\n        x++;\n    }).then(^{\n        XCTAssertEqual(x, 3);\n        x++;\n    }).then(^{\n        XCTAssertEqual(x, 4);\n        x++;\n\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n\n    XCTAssertEqual(x, 5);\n}\n\n- (void)test_10_then_returns_resolved_promise {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(@10);\n    }].then(^(id o){\n        XCTAssertEqualObjects(@10, o);\n        return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n            resolve(@100);\n        }];\n    }).then(^(id o){\n        XCTAssertEqualObjects(@100, o);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_11_then_returns_pending_promise {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(@1);\n    }].then(^{\n        return fulfillLater();\n    }).then(^(id o){\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_12_then_returns_recursive_promises {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    id ex2 = [self expectationWithDescription:@\"\"];\n\n    __block int x = 0;\n    fulfillLater().then(^{\n        NSLog(@\"1\");\n        XCTAssertEqual(x++, 0);\n        return fulfillLater().then(^{\n            NSLog(@\"2\");\n            XCTAssertEqual(x++, 1);\n            return fulfillLater().then(^{\n                NSLog(@\"3\");\n                XCTAssertEqual(x++, 2);\n                return fulfillLater().then(^{\n                    NSLog(@\"4\");\n                    XCTAssertEqual(x++, 3);\n                    [ex2 fulfill];\n                    return @\"foo\";\n                });\n            });\n        });\n    }).then(^(id o){\n                NSLog(@\"5\");\n        XCTAssertEqualObjects(@\"foo\", o);\n        XCTAssertEqual(x++, 4);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n\n    XCTAssertEqual(x, 5);\n}\n\n - (void)test_13_then_returns_recursive_promises_that_fails {\n     id ex1 = [self expectationWithDescription:@\"\"];\n     id ex2 = [self expectationWithDescription:@\"\"];\n\n     fulfillLater().then(^{\n         return fulfillLater().then(^{\n             return fulfillLater().then(^{\n                 return fulfillLater().then(^{\n                     [ex2 fulfill];\n                     return dummy();\n                 });\n             });\n         });\n     }).then(^{\n         XCTFail();\n     }).catch(^(NSError *e){\n         XCTAssertEqualObjects(e.domain, PMKTestErrorDomain);\n         [ex1 fulfill];\n     });\n\n     [self waitForExpectationsWithTimeout:1 handler:nil];\n }\n\n- (void)test_14_fail_returns_value {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(@1);\n    }].then(^{\n        return [NSError errorWithDomain:@\"a\" code:1 userInfo:nil];\n    }).catch(^(NSError *e){\n        XCTAssertEqual(e.code, 1);\n        return @2;\n    }).then(^(id o){\n        XCTAssertEqualObjects(o, @2);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_15_fail_returns_promise {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(@1);\n    }].then(^{\n        return dummy();\n    }).catch(^{\n        return fulfillLater().then(^{\n            return @123;\n        });\n    }).then(^(id o){\n        XCTAssertEqualObjects(o, @123);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_23_add_another_fail_to_already_rejected {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    id ex2 = [self expectationWithDescription:@\"\"];\n\n    PMKResolver resolve;\n    AnyPromise *promise = [[AnyPromise alloc] initWithResolver:&resolve];\n\n    promise.then(^{\n        XCTFail();\n    }).catch(^(NSError *e){\n        XCTAssertEqualObjects(e.localizedDescription, @\"23\");\n        [ex1 fulfill];\n    });\n\n    resolve(dummyWithCode(23));\n\n    promise.then(^{\n        XCTFail();\n    }).catch(^(NSError *e){\n        XCTAssertEqualObjects(e.localizedDescription, @\"23\");\n        [ex2 fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_25_then_plus_deferred_plus_GCD {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    id ex2 = [self expectationWithDescription:@\"\"];\n    id ex3 = [self expectationWithDescription:@\"\"];\n\n    fulfillLater().then(^(id o){\n        [ex1 fulfill];\n        return fulfillLater().then(^{\n            return @YES;\n        });\n    }).then(^(id o){\n        XCTAssertEqualObjects(@YES, o);\n        [ex2 fulfill];\n    }).then(^(id o){\n        XCTAssertNil(o);\n        [ex3 fulfill];\n    }).catch(^{\n        XCTFail();\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_26_promise_then_promise_fail_promise_fail {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    fulfillLater().then(^{\n        return fulfillLater().then(^{\n            return dummy();\n        }).catch(^{\n            return fulfillLater().then(^{\n                return dummy();\n            });\n        });\n    }).then(^{\n        XCTFail();\n    }).catch(^{\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];}\n\n- (void)test_27_eat_failure {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    fulfillLater().then(^{\n        return dummy();\n    }).catch(^{\n        return @YES;\n    }).then(^{\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_28_deferred_rejected_catch_promise {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    id ex2 = [self expectationWithDescription:@\"\"];\n\n    rejectLater().catch(^{\n        [ex1 fulfill];\n        return fulfillLater();\n    }).then(^(id o){\n        [ex2 fulfill];\n    }).catch(^{\n        XCTFail();\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_29_deferred_rejected_catch_promise {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    id ex2 = [self expectationWithDescription:@\"\"];\n\n    rejectLater().catch(^{\n        [ex1 fulfill];\n        return fulfillLater().then(^{\n            return dummy();\n        });\n    }).then(^{\n        XCTFail(@\"1\");\n    }).catch(^(NSError *error){\n        [ex2 fulfill];\n    }).catch(^{\n        XCTFail(@\"2\");\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_30_dispatch_returns_pending_promise {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    dispatch_promise(^{\n        return fulfillLater();\n    }).then(^{\n        [ex1 fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_31_dispatch_returns_promise {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    dispatch_promise(^{\n        return [AnyPromise promiseWithValue:@1];\n    }).then(^(id o){\n        XCTAssertEqualObjects(o, @1);\n        [ex1 fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_32_return_primitive {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    __block void (^fulfiller)(id) = nil;\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        fulfiller = resolve;\n    }].then(^(id o){\n        XCTAssertEqualObjects(o, @32);\n        return 3;\n    }).then(^(id o){\n        XCTAssertEqualObjects(@3, o);\n        [ex1 fulfill];\n    });\n    fulfiller(@32);\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_33_return_nil {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    [AnyPromise promiseWithValue:@1].then(^(id o){\n        XCTAssertEqualObjects(o, @1);\n        return nil;\n    }).then(^{\n        return nil;\n    }).then(^(id o){\n        XCTAssertNil(o);\n        [ex1 fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_33a_return_nil {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    id ex2 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithValue:@\"HI\"].then(^(id o){\n        XCTAssertEqualObjects(o, @\"HI\");\n        [ex1 fulfill];\n        return nil;\n    }).then(^{\n        return nil;\n    }).then(^{\n        [ex2 fulfill];\n        return nil;\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_36_promise_with_value_nil {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithValue:nil].then(^(id o){\n        XCTAssertNil(o);\n        [ex1 fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_42 {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithValue:@1].then(^{\n        return fulfillLater();\n    }).then(^{\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_43_return_promise_from_itself {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    AnyPromise *p = fulfillLater().then(^{ return @1; });\n    p.then(^{\n        return p;\n    }).then(^{\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_44_reseal {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(@123);\n        resolve(@234);\n    }].then(^(id o){\n        XCTAssertEqualObjects(o, @123);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_46_test_then_on {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    dispatch_queue_t q1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);\n    dispatch_queue_t q2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n    [AnyPromise promiseWithValue:@1].thenOn(q1, ^{\n        XCTAssertFalse([NSThread isMainThread]);\n        return dispatch_get_current_queue();\n    }).thenOn(q2, ^(id q){\n        XCTAssertFalse([NSThread isMainThread]);\n        XCTAssertNotEqualObjects(q, dispatch_get_current_queue());\n        [ex1 fulfill];\n    });\n#pragma clang diagnostic pop\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_47_finally_plus {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithValue:@1].then(^{\n        return @1;\n    }).ensure(^{\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_48_finally_negative {\n    @autoreleasepool {\n        id ex1 = [self expectationWithDescription:@\"always\"];\n        id ex2 = [self expectationWithDescription:@\"errorUnhandler\"];\n\n        [AnyPromise promiseWithValue:@1].then(^{\n            return dummy();\n        }).ensure(^{\n            [ex1 fulfill];\n        }).catch(^(NSError *err){\n            XCTAssertEqualObjects(err.domain, PMKTestErrorDomain);\n            [ex2 fulfill];\n        });\n    }\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_49_finally_negative_later {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    __block int x = 0;\n\n    [AnyPromise promiseWithValue:@1].then(^{\n        XCTAssertEqual(++x, 1);\n        return dummy();\n    }).catch(^{\n        XCTAssertEqual(++x, 2);\n    }).then(^{\n        XCTAssertEqual(++x, 3);\n    }).ensure(^{\n        XCTAssertEqual(++x, 4);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_50_fulfill_with_pending_promise {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(fulfillLater().then(^{ return @\"HI\"; }));\n    }].then(^(id hi){\n        XCTAssertEqualObjects(hi, @\"HI\");\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_51_fulfill_with_fulfilled_promise {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve([AnyPromise promiseWithValue:@1]);\n    }].then(^(id o){\n        XCTAssertEqualObjects(o, @1);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_52_fulfill_with_rejected_promise {  //NEEDEDanypr\n    id ex1 = [self expectationWithDescription:@\"\"];\n    fulfillLater().then(^{\n        return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n            resolve([AnyPromise promiseWithValue:dummy()]);\n        }];\n    }).catch(^(NSError *err){\n        [ex1 fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_53_return_rejected_promise {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    fulfillLater().then(^{\n        return @1;\n    }).then(^{\n        return [AnyPromise promiseWithValue:dummy()];\n    }).catch(^{\n        [ex1 fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_54_reject_with_rejected_promise {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        id err = [NSError errorWithDomain:@\"a\" code:123 userInfo:nil];\n        resolve([AnyPromise promiseWithValue:err]);\n    }].catch(^(NSError *err){\n        XCTAssertEqual(err.code, 123);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_58_just_finally {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    AnyPromise *promise = fulfillLater().then(^{\n        return nil;\n    }).ensure(^{\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n\n    id ex2 = [self expectationWithDescription:@\"\"];\n\n    promise.ensure(^{\n        [ex2 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_59_catch_in_background {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        id err = [NSError errorWithDomain:@\"a\" code:123 userInfo:nil];\n        resolve(err);\n    }].catchInBackground(^(NSError *err){\n        XCTAssertEqual(err.code, 123);\n        XCTAssertFalse([NSThread isMainThread]);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_60_catch_on_specific_queue {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    NSString *expectedQueueName = @\"specific queue 123\";\n    dispatch_queue_t q = dispatch_queue_create(expectedQueueName.UTF8String, DISPATCH_QUEUE_SERIAL);\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        id err = [NSError errorWithDomain:@\"a\" code:123 userInfo:nil];\n        resolve(err);\n    }].catchOn(q, ^(NSError *err){\n        XCTAssertEqual(err.code, 123);\n        XCTAssertFalse([NSThread isMainThread]);\n        NSString *currentQueueName = [NSString stringWithFormat:@\"%s\", dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];\n        XCTAssertEqualObjects(expectedQueueName, currentQueueName);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_61_wait_for_value {\n    id o = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(@1);\n    }].wait;\n\n    XCTAssertEqualObjects(o, @1);\n}\n\n- (void)test_62_wait_for_error {\n    NSError* err = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve([NSError errorWithDomain:@\"a\" code:123 userInfo:nil]);\n    }].wait;\n\n    XCTAssertEqual(err.code, 123);\n}\n\n- (void)test_properties {\n    XCTAssertEqualObjects([AnyPromise promiseWithValue:@1].value, @1);\n    XCTAssertEqualObjects([[AnyPromise promiseWithValue:dummyWithCode(2)].value localizedDescription], @\"2\");\n    XCTAssertNil([AnyPromise promiseWithResolverBlock:^(id a){}].value);\n    XCTAssertTrue([AnyPromise promiseWithResolverBlock:^(id a){}].pending);\n    XCTAssertFalse([AnyPromise promiseWithValue:@1].pending);\n    XCTAssertTrue([AnyPromise promiseWithValue:@1].fulfilled);\n    XCTAssertFalse([AnyPromise promiseWithValue:@1].rejected);\n}\n\n- (void)test_promiseWithValue {\n    XCTAssertEqual([AnyPromise promiseWithValue:@1].value, @1);\n    XCTAssertEqualObjects([[AnyPromise promiseWithValue:dummyWithCode(2)].value localizedDescription], @\"2\");\n    XCTAssertEqual([AnyPromise promiseWithValue:[AnyPromise promiseWithValue:@1]].value, @1);\n}\n\n- (void)testInBackground {\n    id ex = [self expectationWithDescription:@\"\"];\n    PMKAfter(0.1).thenInBackground(^{ [ex fulfill]; });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)testEnsureOn {\n    id ex = [self expectationWithDescription:@\"\"];\n    PMKAfter(0.1).ensureOn(dispatch_get_global_queue(QOS_CLASS_UNSPECIFIED, 0), ^{ [ex fulfill]; });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)testEnsureInBackground {\n    id ex = [self expectationWithDescription:@\"\"];\n    PMKAfter(0.1).ensureInBackground(^{ [ex fulfill]; });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)testAdapterBlock {\n    void (^fetch)(PMKAdapter) = ^(PMKAdapter block){\n        block(@1, nil);\n    };\n    id ex = [self expectationWithDescription:@\"\"];\n    [AnyPromise promiseWithAdapterBlock:fetch].then(^(id obj){\n        XCTAssertEqualObjects(obj, @1);\n        [ex fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)testIntegerAdapterBlock {\n    void (^fetch)(PMKIntegerAdapter) = ^(PMKIntegerAdapter block){\n        block(1, nil);\n    };\n    id ex = [self expectationWithDescription:@\"\"];\n    [AnyPromise promiseWithIntegerAdapterBlock:fetch].then(^(id obj){\n        XCTAssertEqualObjects(obj, @1);\n        [ex fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)testBooleanAdapterBlock {\n    void (^fetch)(PMKBooleanAdapter) = ^(PMKBooleanAdapter block){\n        block(YES, nil);\n    };\n    id ex = [self expectationWithDescription:@\"\"];\n    [AnyPromise promiseWithBooleanAdapterBlock:fetch].then(^(id obj){\n        XCTAssertEqualObjects(obj, @YES);\n        [ex fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\nstatic NSHashTable *errorArray;\n\n- (void)setUp {\n    [super setUp];\n    errorArray = [NSHashTable weakObjectsHashTable];\n}\n\n- (void)testErrorLeaks {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    NSError *error = dummyWithCode(1001);\n    [errorArray addObject:error];\n    [AnyPromise promiseWithValue:error]\n    .then(^{\n        XCTFail();\n    }).catch(^(NSError *e){\n        XCTAssertEqual(e.localizedDescription.intValue, 1001);\n    }).then(^{\n        NSError *err = dummyWithCode(1002);\n        [errorArray addObject:err];\n        return err;\n    }).catch(^(NSError *e){\n        XCTAssertEqual(e.localizedDescription.intValue, 1002);\n    }).then(^{\n        NSError *err = dummyWithCode(1003);\n        [errorArray addObject:err];\n        return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve){\n            resolve(err);\n        }];\n    }).catch(^(NSError *e){\n        XCTAssertEqual(e.localizedDescription.intValue, 1003);\n        NSError *err = dummyWithCode(1004);\n        [errorArray addObject:err];\n        return err;\n    }).catch(^(NSError *e){\n        XCTAssertEqual(e.localizedDescription.intValue, 1004);\n    }).then(^{\n        NSError *err = dummyWithCode(1005);\n        [errorArray addObject:err];\n        // throw will lead to leak, if not use complie flag with \"-fobjc-arc-exceptions\"\n        @throw err;\n    }).catch(^(NSError *e){\n        XCTAssertEqual(e.localizedDescription.intValue, 1005);\n    }).ensure(^{\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)tearDown {\n    XCTAssertEqual(errorArray.allObjects.count, 0);\n    [super tearDown];\n}\n\n//- (void)test_nil_block {\n//    [AnyPromise promiseWithValue:@1].then(nil);\n//    [AnyPromise promiseWithValue:@1].thenOn(nil, nil);\n//    [AnyPromise promiseWithValue:@1].catch(nil);\n//    [AnyPromise promiseWithValue:@1].always(nil);\n//    [AnyPromise promiseWithValue:@1].alwaysOn(nil, nil);\n//}\n\n@end\n"
  },
  {
    "path": "Tests/CoreObjC/AnyPromiseTests.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass AnyPromiseTests: XCTestCase {\n    func testFulfilledResult() {\n        switch AnyPromise(Promise.value(true)).result {\n        case .fulfilled(let obj as Bool)? where obj:\n            break\n        default:\n            XCTFail()\n        }\n    }\n\n    func testRejectedResult() {\n        switch AnyPromise(Promise<Int>(error: PMKError.badInput)).result {\n        case .rejected(let err)?:\n            print(err)\n            break\n        default:\n            XCTFail()\n        }\n    }\n\n    func testPendingResult() {\n        switch AnyPromise(Promise<Int>.pending().promise).result {\n        case nil:\n            break\n        default:\n            XCTFail()\n        }\n    }\n\n    func testCustomStringConvertible() {\n        XCTAssertEqual(\"\\(AnyPromise(Promise<Int>.pending().promise))\", \"AnyPromise(…)\")\n        XCTAssertEqual(\"\\(AnyPromise(Promise.value(1)))\", \"AnyPromise(1)\")\n        XCTAssertEqual(\"\\(AnyPromise(Promise<Int?>.value(nil)))\", \"AnyPromise(nil)\")\n    }\n}\n"
  },
  {
    "path": "Tests/CoreObjC/HangTests.m",
    "content": "@import PromiseKit;\n@import XCTest;\n\n@interface HangTests: XCTestCase @end @implementation HangTests\n\n- (void)test {\n    __block int x = 0;\n    id value = PMKHang(PMKAfter(0.02).then(^{ x++; return 1; }));\n    XCTAssertEqual(x, 1);\n    XCTAssertEqualObjects(value, @1);\n}\n\n@end\n"
  },
  {
    "path": "Tests/CoreObjC/JoinTests.m",
    "content": "@import Foundation;\n@import PromiseKit;\n@import XCTest;\n\n\n@interface JoinTests: XCTestCase @end @implementation JoinTests\n\n- (void)test_73_join {\n    XCTestExpectation *ex1 = [self expectationWithDescription:@\"\"];\n\n    __block void (^fulfiller)(id) = nil;\n    AnyPromise *promise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        fulfiller = resolve;\n    }];\n\n    PMKJoin(@[\n        [AnyPromise promiseWithValue:[NSError errorWithDomain:@\"dom\" code:1 userInfo:nil]],\n        promise,\n        [AnyPromise promiseWithValue:[NSError errorWithDomain:@\"dom\" code:2 userInfo:nil]]\n    ]).then(^{\n        XCTFail();\n    }).catch(^(NSError *error){\n        id promises = error.userInfo[PMKJoinPromisesKey];\n\n        int cume = 0, cumv = 0;\n\n        for (AnyPromise *promise in promises) {\n            if ([promise.value isKindOfClass:[NSError class]]) {\n                cume |= [promise.value code];\n            } else {\n                cumv |= [promise.value unsignedIntValue];\n            }\n        }\n\n        XCTAssertTrue(cumv == 4);\n        XCTAssertTrue(cume == 3);\n\n        [ex1 fulfill];\n    });\n    fulfiller(@4);\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_74_join_no_errors {\n    XCTestExpectation *ex1 = [self expectationWithDescription:@\"\"];\n    PMKJoin(@[\n              [AnyPromise promiseWithValue:@1],\n              [AnyPromise promiseWithValue:@2]\n              ]).then(^(NSArray *values, id errors) {\n        XCTAssertEqualObjects(values, (@[@1, @2]));\n        XCTAssertNil(errors);\n        [ex1 fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n\n- (void)test_75_join_no_success {\n    XCTestExpectation *ex1 = [self expectationWithDescription:@\"\"];\n    PMKJoin(@[\n              [AnyPromise promiseWithValue:[NSError errorWithDomain:@\"dom\" code:1 userInfo:nil]],\n              [AnyPromise promiseWithValue:[NSError errorWithDomain:@\"dom\" code:2 userInfo:nil]],\n              ]).then(^{\n        XCTFail();\n    }).catch(^(NSError *error){\n        XCTAssertNotNil(error.userInfo[PMKJoinPromisesKey]);\n        [ex1 fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_76_join_fulfills_if_empty_input {\n    XCTestExpectation *ex1 = [self expectationWithDescription:@\"\"];\n    PMKJoin(@[]).then(^(id a, id b, id c){\n        XCTAssertEqualObjects(@[], a);\n        XCTAssertNil(b);\n        XCTAssertNil(c);\n        [ex1 fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_join_nil {\n    NSArray *foo = nil;\n    NSError *err = PMKJoin(foo).value;\n    XCTAssertEqual(err.domain, PMKErrorDomain);\n    XCTAssertEqual(err.code, PMKInvalidUsageError);\n}\n\n@end\n"
  },
  {
    "path": "Tests/CoreObjC/PMKManifoldTests.m",
    "content": "@import PromiseKit;\n@import XCTest;\n\n@interface PMKManifoldTests: XCTestCase @end @implementation PMKManifoldTests\n\n- (void)test_62_access_extra_elements {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {\n        resolve(PMKManifold(@1));\n    }].then(^(id o, id m, id n){\n        XCTAssertNil(m, @\"Accessing extra elements should not crash\");\n        XCTAssertNil(n, @\"Accessing extra elements should not crash\");\n        XCTAssertEqualObjects(o, @1);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_63_then_manifold {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithValue:@0].then(^{\n        return PMKManifold(@1, @2, @3);\n    }).then(^(id o1, id o2, id o3){\n        XCTAssertEqualObjects(o1, @1);\n        XCTAssertEqualObjects(o2, @2);\n        XCTAssertEqualObjects(o3, @3);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_63_then_manifold_with_nil {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    [AnyPromise promiseWithValue:@0].then(^{\n        return PMKManifold(@1, nil, @3);\n    }).then(^(id o1, id o2, id o3){\n        XCTAssertEqualObjects(o1, @1);\n        XCTAssertEqualObjects(o2, nil);\n        XCTAssertEqualObjects(o3, @3);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_65_manifold_fulfill_value {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    AnyPromise *promise = [AnyPromise promiseWithValue:@1].then(^{\n        return PMKManifold(@123, @2);\n    });\n\n    promise.then(^(id a, id b){\n        XCTAssertNotNil(a);\n        XCTAssertNotNil(b);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n\n    XCTAssertEqualObjects(promise.value, @123);\n}\n\n- (void)test_37_PMKMany_2 {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    PMKAfter(0.02).then(^{\n        return PMKManifold(@1, @2);\n    }).then(^(id a, id b){\n        XCTAssertEqualObjects(a, @1);\n        XCTAssertEqualObjects(b, @2);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n@end\n"
  },
  {
    "path": "Tests/CoreObjC/RaceTests.m",
    "content": "@import Foundation;\n@import PromiseKit;\n@import XCTest;\n#define PMKTestErrorDomain @\"PMKTestErrorDomain\"\n\nstatic inline NSError *dummyWithCode(NSInteger code) {\n    return [NSError errorWithDomain:PMKTestErrorDomain code:rand() userInfo:@{NSLocalizedDescriptionKey: @(code).stringValue}];\n}\n\n@interface RaceTests : XCTestCase @end @implementation RaceTests\n\n- (void)test_race {\n    id ex = [self expectationWithDescription:@\"\"];\n    id p = PMKAfter(0.1).then(^{ return @2; });\n    PMKRace(@[PMKAfter(10), PMKAfter(20), p]).then(^(id obj){\n        XCTAssertEqual(2, [obj integerValue]);\n        [ex fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_race_empty {\n    id ex = [self expectationWithDescription:@\"\"];\n    PMKRace(@[]).then(^(NSArray* array){\n        XCTFail();\n        [ex fulfill];\n    }).catch(^(NSError *e){\n        XCTAssertEqual(e.domain, PMKErrorDomain);\n        XCTAssertEqual(e.code, PMKInvalidUsageError);\n        XCTAssertEqualObjects(e.userInfo[NSLocalizedDescriptionKey], @\"PMKRace(nil)\");\n        [ex fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_race_fullfilled {\n    id ex = [self expectationWithDescription:@\"\"];\n    NSArray* promises = @[\n        PMKAfter(1).then(^{ return dummyWithCode(1); }),\n        PMKAfter(2).then(^{ return dummyWithCode(2); }),\n        PMKAfter(5).then(^{ return @1; }),\n        PMKAfter(4).then(^{ return @2; }),\n        PMKAfter(3).then(^{ return dummyWithCode(3); })\n    ];\n    PMKRaceFulfilled(promises).then(^(id obj){\n        XCTAssertEqual(2, [obj integerValue]);\n        [ex fulfill];\n    }).catch(^{\n        XCTFail();\n        [ex fulfill];\n    });\n    [self waitForExpectationsWithTimeout:10 handler:nil];\n}\n\n- (void)test_race_fulfilled_empty {\n    id ex = [self expectationWithDescription:@\"\"];\n    PMKRaceFulfilled(@[]).then(^(NSArray* array){\n        XCTFail();\n        [ex fulfill];\n    }).catch(^(NSError *e){\n        XCTAssertEqual(e.domain, PMKErrorDomain);\n        XCTAssertEqual(e.code, PMKInvalidUsageError);\n        XCTAssertEqualObjects(e.userInfo[NSLocalizedDescriptionKey], @\"PMKRaceFulfilled(nil)\");\n        [ex fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_race_fullfilled_with_no_winner {\n    id ex = [self expectationWithDescription:@\"\"];\n    NSArray* promises = @[\n        PMKAfter(1).then(^{ return dummyWithCode(1); }),\n        PMKAfter(2).then(^{ return dummyWithCode(2); }),\n        PMKAfter(3).then(^{ return dummyWithCode(3); })\n    ];\n    PMKRaceFulfilled(promises).then(^(id obj){\n        XCTFail();\n        [ex fulfill];\n    }).catch(^(NSError *e){\n        XCTAssertEqual(e.domain, PMKErrorDomain);\n        XCTAssertEqual(e.code, PMKNoWinnerError);\n        XCTAssertEqualObjects(e.userInfo[NSLocalizedDescriptionKey], @\"PMKRaceFulfilled(nil)\");\n        [ex fulfill];\n    });\n    [self waitForExpectationsWithTimeout:10 handler:nil];\n}\n\n@end\n"
  },
  {
    "path": "Tests/CoreObjC/WhenTests.m",
    "content": "@import Foundation;\n@import PromiseKit;\n@import XCTest;\n\n\n@interface WhenTests: XCTestCase @end @implementation WhenTests\n\n- (void)testProgress {\n\n    id ex = [self expectationWithDescription:@\"\"];\n\n    XCTAssertNil([NSProgress currentProgress]);\n\n    id p1 = PMKAfter(0.01);\n    id p2 = PMKAfter(0.02);\n    id p3 = PMKAfter(0.03);\n    id p4 = PMKAfter(0.04);\n\n    NSProgress *progress = [NSProgress progressWithTotalUnitCount:1];\n    [progress becomeCurrentWithPendingUnitCount:1];\n\n    PMKWhen(@[p1, p2, p3, p4]).then(^{\n        XCTAssertEqual(progress.completedUnitCount, 1);\n        [ex fulfill];\n    });\n\n    [progress resignCurrent];\n\n    [self waitForExpectationsWithTimeout:5 handler:nil];\n}\n\n- (void)testProgressDoesNotExceed100Percent {\n\n    id ex1 = [self expectationWithDescription:@\"\"];\n    id ex2 = [self expectationWithDescription:@\"\"];\n\n    XCTAssertNil([NSProgress currentProgress]);\n\n    id p1 = PMKAfter(0.01);\n    id p2 = PMKAfter(0.02).then(^{ return [NSError errorWithDomain:@\"a\" code:1 userInfo:nil]; });\n    id p3 = PMKAfter(0.03);\n    id p4 = PMKAfter(0.04);\n\n    id promises = @[p1, p2, p3, p4];\n\n    NSProgress *progress = [NSProgress progressWithTotalUnitCount:1];\n    [progress becomeCurrentWithPendingUnitCount:1];\n\n    PMKWhen(promises).catch(^{\n        [ex2 fulfill];\n    });\n\n    [progress resignCurrent];\n\n    PMKJoin(promises).catch(^{\n        XCTAssertLessThanOrEqual(1, progress.fractionCompleted);\n        XCTAssertEqual(progress.completedUnitCount, 1);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)testWhenManifolds {\n    id ex = [self expectationWithDescription:@\"\"];\n    id p1 = dispatch_promise(^{ return PMKManifold(@1, @2); });\n    id p2 = dispatch_promise(^{});\n    PMKWhen(@[p1, p2]).then(^(NSArray *results){\n        XCTAssertEqualObjects(results[0], @1);\n        XCTAssertEqualObjects(results[1], [NSNull null]);\n        [ex fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_55_all_dictionary {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    id promises = @{\n          @1: @2,\n          @2: @\"abc\",\n        @\"a\": PMKAfter(0.1).then(^{ return @\"HI\"; })\n    };\n    PMKWhen(promises).then(^(NSDictionary *dict){\n        XCTAssertEqual(dict.count, 3ul);\n        XCTAssertEqualObjects(dict[@1], @2);\n        XCTAssertEqualObjects(dict[@2], @\"abc\");\n        XCTAssertEqualObjects(dict[@\"a\"], @\"HI\");\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_56_empty_array_when {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    PMKWhen(@[]).then(^(NSArray *array){\n        XCTAssertEqual(array.count, 0ul);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_57_empty_array_all {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    PMKWhen(@[]).then(^(NSArray *array){\n        XCTAssertEqual(array.count, 0ul);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_18_when {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    id a = PMKAfter(0.02).then(^{ return @345; });\n    id b = PMKAfter(0.03).then(^{ return @345; });\n    PMKWhen(@[a, b]).then(^(NSArray *objs){\n        XCTAssertEqual(objs.count, 2ul);\n        XCTAssertEqualObjects(objs[0], objs[1]);\n        [ex1 fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_21_recursive_when {\n    id domain = @\"sdjhfg\";\n\n    id ex1 = [self expectationWithDescription:@\"\"];\n    id a = PMKAfter(0.03).then(^{\n        return [NSError errorWithDomain:domain code:123 userInfo:nil];\n    });\n    id b = PMKAfter(0.02);\n    id c = PMKWhen(@[a, b]);\n    PMKWhen(c).then(^{\n        XCTFail();\n    }).catch(^(NSError *e){\n        XCTAssertEqualObjects(e.userInfo[PMKFailingPromiseIndexKey], @0);\n        XCTAssertEqualObjects(e.domain, domain);\n        [ex1 fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_22_already_resolved_and_bubble {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    id ex2 = [self expectationWithDescription:@\"\"];\n\n    PMKResolver resolve;\n    AnyPromise *promise = [[AnyPromise alloc] initWithResolver:&resolve];\n\n    promise.then(^{\n        XCTFail();\n    }).catch(^(NSError *e){\n        [ex1 fulfill];\n    });\n\n    resolve([NSError errorWithDomain:@\"a\" code:1 userInfo:nil]);\n\n    PMKWhen(promise).then(^{\n        XCTFail();\n    }).catch(^{\n        [ex2 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_24_some_edge_case {\n    id ex1 = [self expectationWithDescription:@\"\"];\n    id a = PMKAfter(0.02).catch(^{});\n    id b = PMKAfter(0.03);\n    PMKWhen(@[a, b]).then(^(NSArray *objs){\n        [ex1 fulfill];\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_35_when_nil {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    AnyPromise *promise = [AnyPromise promiseWithValue:@\"35\"].then(^{ return nil; });\n    PMKWhen(@[PMKAfter(0.02).then(^{ return @1; }), [AnyPromise promiseWithValue:nil], promise]).then(^(NSArray *results){\n        XCTAssertEqual(results.count, 3ul);\n        XCTAssertEqualObjects(results[1], [NSNull null]);\n        [ex1 fulfill];\n    }).catch(^(NSError *err){\n        abort();\n    });\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n\n- (void)test_39_when_with_some_values {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    id p = PMKAfter(0.02);\n    id v = @1;\n    PMKWhen(@[p, v]).then(^(NSArray *aa){\n        XCTAssertEqual(aa.count, 2ul);\n        XCTAssertEqualObjects(aa[1], @1);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_40_when_with_all_values {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    PMKWhen(@[@1, @2]).then(^(NSArray *aa){\n        XCTAssertEqualObjects(aa[0], @1);\n        XCTAssertEqualObjects(aa[1], @2);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_41_when_with_repeated_promises {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    id p = PMKAfter(0.02);\n    id v = @1;\n    PMKWhen(@[p, v, p, v]).then(^(NSArray *aa){\n        XCTAssertEqual(aa.count, 4ul);\n        XCTAssertEqualObjects(aa[1], @1);\n        XCTAssertEqualObjects(aa[3], @1);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_45_when_which_returns_void {\n    id ex1 = [self expectationWithDescription:@\"\"];\n\n    AnyPromise *promise = [AnyPromise promiseWithValue:@1].then(^{});\n    PMKWhen(@[promise, [AnyPromise promiseWithValue:@1]]).then(^(NSArray *stuff){\n        XCTAssertEqual(stuff.count, 2ul);\n        XCTAssertEqualObjects(stuff[0], [NSNull null]);\n        [ex1 fulfill];\n    });\n\n    [self waitForExpectationsWithTimeout:1 handler:nil];\n}\n\n- (void)test_when_nil {\n    NSArray *foo = nil;\n    NSError *err = PMKWhen(foo).value;\n    XCTAssertEqual(err.domain, PMKErrorDomain);\n    XCTAssertEqual(err.code, PMKInvalidUsageError);\n}\n\n\n- (void)test_when_bad_input {\n    id foo = @\"a\";\n    XCTAssertEqual(PMKWhen(foo).value, foo);\n}\n\n@end\n"
  },
  {
    "path": "Tests/CorePromise/AfterTests.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass AfterTests: XCTestCase {\n    func testZero() {\n        let ex2 = expectation(description: \"\")\n        after(seconds: 0).done(ex2.fulfill)\n        waitForExpectations(timeout: 2, handler: nil)\n\n        let ex3 = expectation(description: \"\")\n        after(.seconds(0)).done(ex3.fulfill)\n        waitForExpectations(timeout: 2, handler: nil)\n\n    #if !SWIFT_PACKAGE\n        let ex4 = expectation(description: \"\")\n        __PMKAfter(0).done{ _ in ex4.fulfill() }.silenceWarning()\n        waitForExpectations(timeout: 2, handler: nil)\n    #endif\n    }\n\n    func testNegative() {\n        let ex2 = expectation(description: \"\")\n        after(seconds: -1).done(ex2.fulfill)\n        waitForExpectations(timeout: 2, handler: nil)\n\n        let ex3 = expectation(description: \"\")\n        after(.seconds(-1)).done(ex3.fulfill)\n        waitForExpectations(timeout: 2, handler: nil)\n\n    #if !SWIFT_PACKAGE\n        let ex4 = expectation(description: \"\")\n        __PMKAfter(-1).done{ _ in ex4.fulfill() }.silenceWarning()\n        waitForExpectations(timeout: 2, handler: nil)\n    #endif\n    }\n\n    func testPositive() {\n        let ex2 = expectation(description: \"\")\n        after(seconds: 1).done(ex2.fulfill)\n        waitForExpectations(timeout: 2, handler: nil)\n\n        let ex3 = expectation(description: \"\")\n        after(.seconds(1)).done(ex3.fulfill)\n        waitForExpectations(timeout: 2, handler: nil)\n\n    #if !SWIFT_PACKAGE\n        let ex4 = expectation(description: \"\")\n        __PMKAfter(1).done{ _ in ex4.fulfill() }.silenceWarning()\n        waitForExpectations(timeout: 2, handler: nil)\n    #endif\n    }\n}\n"
  },
  {
    "path": "Tests/CorePromise/AsyncTests.swift",
    "content": "import PromiseKit\nimport XCTest\n\nprivate enum Error: Swift.Error { case dummy }\n\nclass AsyncTests: XCTestCase {\n    \n    #if swift(>=5.5)\n    #if canImport(_Concurrency)\n    @available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)\n    func testAsyncPromiseValue() async throws {\n        let promise = after(.milliseconds(100)).then(on: nil){ Promise.value(1) }\n        let value = try await promise.async()\n        XCTAssertEqual(value, 1)\n    }\n    \n    @available(iOS, deprecated: 13.0)\n    @available(macOS, deprecated: 10.15)\n    @available(tvOS, deprecated: 13.0)\n    @available(watchOS, deprecated: 6.0)\n    func testAsyncPromiseValue() {\n\n    }\n    #else\n    func testAsyncPromiseValue() {\n\n    }\n    #endif\n    #else\n    func testAsyncPromiseValue() {\n\n    }\n    #endif\n    \n    #if swift(>=5.5)\n    #if canImport(_Concurrency)\n    @available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)\n    func testAsyncGuaranteeValue() async {\n        let guarantee = after(.milliseconds(100)).then(on: nil){ Guarantee.value(1) }\n        let value = await guarantee.async()\n        XCTAssertEqual(value, 1)\n    }\n    \n    @available(iOS, deprecated: 13.0)\n    @available(macOS, deprecated: 10.15)\n    @available(tvOS, deprecated: 13.0)\n    @available(watchOS, deprecated: 6.0)\n    func testAsyncGuaranteeValue() {\n\n    }\n    #else\n    func testAsyncGuaranteeValue() {\n\n    }\n    #endif\n    #else\n    func testAsyncGuaranteeValue() {\n\n    }\n    #endif\n    \n    #if swift(>=5.5)\n    #if canImport(_Concurrency)\n    @available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)\n    func testAsyncPromiseThrow() async throws {\n        do {\n            let promise = after(.milliseconds(100)).then(on: nil){ Promise(error: Error.dummy) }.then(on: nil){ Promise.value(1) }\n            try await _ = promise.async()\n            XCTAssert(false)\n        } catch {\n            switch error as? Error {\n            case .dummy:\n                XCTAssert(true)\n            default:\n                XCTAssert(false)\n            }\n        }\n    }\n    \n    @available(iOS, deprecated: 13.0)\n    @available(macOS, deprecated: 10.15)\n    @available(tvOS, deprecated: 13.0)\n    @available(watchOS, deprecated: 6.0)\n    func testAsyncPromiseThrow() {\n\n    }\n    #else\n    func testAsyncPromiseThrow() {\n\n    }\n    #endif\n    #else\n    func testAsyncPromiseThrow() {\n\n    }\n    #endif\n    \n    #if swift(>=5.5)\n    #if canImport(_Concurrency)\n    @available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)\n    func testAsyncPromiseCancel() async throws {\n        do {\n            let p = after(seconds: 0).done { _ in\n                throw LocalError.cancel\n            }.done {\n                XCTFail()\n            }\n            p.catch { _ in\n                XCTFail()\n            }\n            try await p.async()\n            XCTAssert(false)\n        } catch {\n            guard let cancellableError = error as? CancellableError else { return XCTFail(\"Unexpected error type\") }\n            XCTAssertTrue(cancellableError.isCancelled)\n        }\n    }\n    \n    @available(iOS, deprecated: 13.0)\n    @available(macOS, deprecated: 10.15)\n    @available(tvOS, deprecated: 13.0)\n    @available(watchOS, deprecated: 6.0)\n    func testAsyncPromiseCancel() {\n        \n    }\n    #else\n    func testAsyncPromiseCancel() {\n        \n    }\n    #endif\n    #else\n    func testAsyncPromiseCancel() {\n        \n    }\n    #endif\n}\n\nprivate enum LocalError: CancellableError {\n    case notCancel\n    case cancel\n    \n    var isCancelled: Bool {\n        switch self {\n        case .notCancel: return false\n        case .cancel: return true\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/CorePromise/CancellableErrorTests.swift",
    "content": "import Foundation\nimport PromiseKit\nimport XCTest\n\n#if canImport(StoreKit)\nimport StoreKit\n#endif\n\nclass CancellationTests: XCTestCase {\n    func testCancellation() {\n        let ex1 = expectation(description: \"\")\n\n        let p = after(seconds: 0).done { _ in\n            throw LocalError.cancel\n        }.done {\n            XCTFail()\n        }\n        p.catch { _ in\n            XCTFail()\n        }\n        p.catch(policy: .allErrors) {\n            XCTAssertTrue($0.isCancelled)\n            ex1.fulfill()\n        }\n\n        waitForExpectations(timeout: 60)\n    }\n\n    func testThrowCancellableErrorThatIsNotCancelled() {\n        let expct = expectation(description: \"\")\n\n        after(seconds: 0).done { _ in\n            throw LocalError.notCancel\n        }.done {\n            XCTFail()\n        }.catch {\n            XCTAssertFalse($0.isCancelled)\n            expct.fulfill()\n        }\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testRecoverWithCancellation() {\n        let ex1 = expectation(description: \"\")\n        let ex2 = expectation(description: \"\")\n\n        let p = after(seconds: 0).done { _ in\n            throw CocoaError.cancelled\n        }.recover(policy: .allErrors) { err -> Promise<Void> in\n            ex1.fulfill()\n            XCTAssertTrue(err.isCancelled)\n            throw err\n        }.done { _ in\n            XCTFail()\n        }\n        p.catch { _ in\n            XCTFail()\n        }\n        p.catch(policy: .allErrors) {\n            XCTAssertTrue($0.isCancelled)\n            ex2.fulfill()\n        }\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testFoundationBridging1() {\n        let ex = expectation(description: \"\")\n\n        let p = after(seconds: 0).done { _ in\n            throw CocoaError.cancelled\n        }\n        p.catch { _ in\n            XCTFail()\n        }\n        p.catch(policy: .allErrors) {\n            XCTAssertTrue($0.isCancelled)\n            ex.fulfill()\n        }\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testFoundationBridging2() {\n        let ex = expectation(description: \"\")\n\n        let p = Promise().done {\n            throw URLError.cancelled\n        }\n        p.catch { _ in\n            XCTFail()\n        }\n        p.catch(policy: .allErrors) {\n            XCTAssertTrue($0.isCancelled)\n            ex.fulfill()\n        }\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testDoesntCrashSwift() {\n      #if canImport(StoreKit)\n        if #available(watchOS 6.2, *) {\n            do {\n                let err = SKError(.paymentCancelled)\n                XCTAssertTrue(err.isCancelled)\n                throw err\n            } catch {\n                XCTAssertTrue(error.isCancelled)\n            }\n            \n            XCTAssertFalse(SKError(.clientInvalid).isCancelled)\n        }\n      #endif\n    }\n\n    func testBridgeToNSError() {\n        // Swift.Error types must be cast to NSError for the bridging to occur.\n        // The below would throw an expection about an invalid selector without a cast:\n        // `(error as AnyObject).value(forKey: \"domain\")`\n        // This simply checks to make sure `isCancelled` is not making that mistake.\n\n        class TestingError: Error { }\n\n        XCTAssertFalse(TestingError().isCancelled)\n    }\n\n#if swift(>=3.2)\n    func testIsCancelled() {\n        XCTAssertTrue(PMKError.cancelled.isCancelled)\n        XCTAssertTrue(URLError.cancelled.isCancelled)\n        XCTAssertTrue(CocoaError.cancelled.isCancelled)\n        XCTAssertFalse(CocoaError(_nsError: NSError(domain: NSCocoaErrorDomain, code: CocoaError.Code.coderInvalidValue.rawValue)).isCancelled)\n    }\n#endif\n}\n\nprivate enum LocalError: CancellableError {\n    case notCancel\n    case cancel\n\n    var isCancelled: Bool {\n        switch self {\n            case .notCancel: return false\n            case .cancel: return true\n        }\n    }\n}\n\nprivate extension URLError {\n    static var cancelled: URLError {\n        return .init(_nsError: NSError(domain: NSURLErrorDomain, code: URLError.Code.cancelled.rawValue))\n    }\n}\n\nprivate extension CocoaError {\n    static var cancelled: CocoaError {\n        return .init(_nsError: NSError(domain: NSCocoaErrorDomain, code: CocoaError.Code.userCancelled.rawValue))\n    }\n}\n"
  },
  {
    "path": "Tests/CorePromise/CatchableTests.swift",
    "content": "import PromiseKit\nimport Dispatch\nimport XCTest\n\nclass CatchableTests: XCTestCase {\n\n    func testFinally() {\n        let finallyQueue = DispatchQueue(label: \"\\(#file):\\(#line)\", attributes: .concurrent)\n\n        func helper(error: Error, on queue: DispatchQueue = .main, flags: DispatchWorkItemFlags? = nil) {\n            let ex = (expectation(description: \"\"), expectation(description: \"\"))\n            var x = 0\n            Promise<Void>(error: error).catch(policy: .allErrors) { _ in\n                XCTAssertEqual(x, 0)\n                x += 1\n                ex.0.fulfill()\n            }.finally(on: queue, flags: flags) {\n                if let flags = flags, flags.contains(.barrier) {\n                    dispatchPrecondition(condition: .onQueueAsBarrier(queue))\n                } else {\n                    dispatchPrecondition(condition: .onQueue(queue))\n                }\n                XCTAssertEqual(x, 1)\n                x += 1\n                ex.1.fulfill()\n            }\n            wait(for: [ex.0, ex.1], timeout: 10)\n        }\n\n        helper(error: Error.dummy)\n        helper(error: Error.cancelled)\n        helper(error: Error.dummy, on: finallyQueue)\n        helper(error: Error.dummy, on: finallyQueue, flags: .barrier)\n    }\n\n    func testCauterize() {\n        let ex = expectation(description: \"\")\n        let p = Promise<Void>(error: Error.dummy)\n\n        // cannot test specifically that this outputs to console,\n        // but code-coverage will note that the line is run\n        p.cauterize()\n\n        p.catch { _ in\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 1)\n    }\n}\n\n\n/// `Promise<Void>.recover`\nextension CatchableTests {\n    func test__void_specialized_full_recover() {\n\n        func helper(error: Swift.Error) {\n            let ex = expectation(description: \"\")\n            Promise<Void>(error: error).recover { _ in }.done(ex.fulfill)\n            wait(for: [ex], timeout: 10)\n        }\n\n        helper(error: Error.dummy)\n        helper(error: Error.cancelled)\n    }\n\n    func test__void_specialized_full_recover__fulfilled_path() {\n        let ex = expectation(description: \"\")\n        Promise().recover { _ in XCTFail() }.done(ex.fulfill)\n        wait(for: [ex], timeout: 10)\n    }\n\n    func test__void_specialized_conditional_recover() {\n        func helper(policy: CatchPolicy, error: Swift.Error, line: UInt = #line) {\n            let ex = expectation(description: \"\")\n            var x = 0\n            Promise<Void>(error: error).recover(policy: policy) { err in\n                guard x < 1 else { throw err }\n                x += 1\n            }.done(ex.fulfill).silenceWarning()\n            wait(for: [ex], timeout: 10)\n        }\n\n        for error in [Error.dummy as Swift.Error, Error.cancelled] {\n            helper(policy: .allErrors, error: error)\n        }\n        helper(policy: .allErrorsExceptCancellation, error: Error.dummy)\n    }\n\n    func test__void_specialized_conditional_recover__no_recover() {\n\n        func helper(policy: CatchPolicy, error: Error, line: UInt = #line) {\n            let ex = expectation(description: \"\")\n            Promise<Void>(error: error).recover(policy: policy) { err in\n                throw err\n            }.catch(policy: .allErrors) {\n                XCTAssertEqual(error, $0 as? Error)\n                ex.fulfill()\n            }\n            wait(for: [ex], timeout: 10)\n        }\n\n        for error in [Error.dummy, Error.cancelled] {\n            helper(policy: .allErrors, error: error)\n        }\n        helper(policy: .allErrorsExceptCancellation, error: Error.dummy)\n    }\n\n    func test__void_specialized_conditional_recover__ignores_cancellation_but_fed_cancellation() {\n        let ex = expectation(description: \"\")\n        Promise<Void>(error: Error.cancelled).recover(policy: .allErrorsExceptCancellation) { _ in\n            XCTFail()\n        }.catch(policy: .allErrors) {\n            XCTAssertEqual(Error.cancelled, $0 as? Error)\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func test__void_specialized_conditional_recover__fulfilled_path() {\n        let ex = expectation(description: \"\")\n        Promise().recover { _ in\n            XCTFail()\n        }.catch { _ in\n            XCTFail()   // this `catch` to ensure we are calling the `recover` variant we think we are\n        }.finally {\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n}\n\n\n/// `Promise<T>.recover`\nextension CatchableTests {\n    func test__full_recover() {\n\n        func helper(error: Swift.Error) {\n            let ex = expectation(description: \"\")\n            Promise<Int>(error: error).recover { _ in return .value(2) }.done {\n                XCTAssertEqual($0, 2)\n                ex.fulfill()\n            }\n            wait(for: [ex], timeout: 10)\n        }\n\n        helper(error: Error.dummy)\n        helper(error: Error.cancelled)\n    }\n\n    func test__full_recover__fulfilled_path() {\n        let ex = expectation(description: \"\")\n        Promise.value(1).recover { _ in XCTFail(); return .value(2) }.done{\n            XCTAssertEqual($0, 1)\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n\n    func test__conditional_recover() {\n        func helper(policy: CatchPolicy, error: Swift.Error, line: UInt = #line) {\n            let ex = expectation(description: \"\")\n            var x = 0\n            Promise<Int>(error: error).recover(policy: policy) { err -> Promise<Int> in\n                guard x < 1 else { throw err }\n                x += 1\n                return .value(x)\n            }.done {\n                XCTAssertEqual($0, x)\n                ex.fulfill()\n            }.silenceWarning()\n            wait(for: [ex], timeout: 10)\n        }\n\n        for error in [Error.dummy as Swift.Error, Error.cancelled] {\n            helper(policy: .allErrors, error: error)\n        }\n        helper(policy: .allErrorsExceptCancellation, error: Error.dummy)\n    }\n\n    func test__conditional_recover__no_recover() {\n\n        func helper(policy: CatchPolicy, error: Error, line: UInt = #line) {\n            let ex = expectation(description: \"\")\n            Promise<Int>(error: error).recover(policy: policy) { err -> Promise<Int> in\n                throw err\n            }.catch(policy: .allErrors) {\n                XCTAssertEqual(error, $0 as? Error)\n                ex.fulfill()\n            }\n            wait(for: [ex], timeout: 10)\n        }\n\n        for error in [Error.dummy, Error.cancelled] {\n            helper(policy: .allErrors, error: error)\n        }\n        helper(policy: .allErrorsExceptCancellation, error: Error.dummy)\n    }\n\n    func test__conditional_recover__ignores_cancellation_but_fed_cancellation() {\n        let ex = expectation(description: \"\")\n        Promise<Int>(error: Error.cancelled).recover(policy: .allErrorsExceptCancellation) { _ -> Promise<Int> in\n            XCTFail()\n            return .value(1)\n        }.catch(policy: .allErrors) {\n            XCTAssertEqual(Error.cancelled, $0 as? Error)\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func test__conditional_recover__fulfilled_path() {\n        let ex = expectation(description: \"\")\n        Promise.value(1).recover { err -> Promise<Int> in\n            XCTFail()\n            throw err\n        }.done {\n            XCTAssertEqual($0, 1)\n            ex.fulfill()\n        }.catch { _ in\n            XCTFail()   // this `catch` to ensure we are calling the `recover` variant we think we are\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testEnsureThen_Error() {\n        let ex = expectation(description: \"\")\n\n        Promise.value(1).done {\n            XCTAssertEqual($0, 1)\n            throw Error.dummy\n        }.ensureThen {\n            after(seconds: 0.01)\n        }.catch {\n            XCTAssertEqual(Error.dummy, $0 as? Error)\n        }.finally {\n            ex.fulfill()\n        }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testEnsureThen_Value() {\n        let ex = expectation(description: \"\")\n\n        Promise.value(1).ensureThen {\n            after(seconds: 0.01)\n        }.done {\n            XCTAssertEqual($0, 1)\n        }.catch { _ in\n            XCTFail()\n        }.finally {\n            ex.fulfill()\n        }\n\n        wait(for: [ex], timeout: 10)\n    }\n}\n\nprivate enum Error: CancellableError {\n    case dummy\n    case cancelled\n\n    var isCancelled: Bool {\n        return self == Error.cancelled\n    }\n}\n"
  },
  {
    "path": "Tests/CorePromise/CombineTests.swift",
    "content": "#if swift(>=4.1)\n#if canImport(Combine)\nimport Combine\n#endif\n#endif\nimport PromiseKit\nimport XCTest\n\nprivate enum Error: Swift.Error { case dummy }\n\nclass CombineTests: XCTestCase {\n    private var cancellable: Any?\n    \n    override func tearDown() {\n        #if swift(>=4.1)\n        #if canImport(Combine)\n        if #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) {\n            (cancellable as? AnyCancellable)?.cancel()\n        }\n        #endif\n        #endif\n    }\n    \n    func testCombinePromiseValue() {\n        let ex = expectation(description: \"\")\n        #if swift(>=4.1)\n        #if canImport(Combine)\n        if #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) {\n            let promise = after(.milliseconds(100)).then(on: nil){ Promise.value(1) }\n            cancellable = promise.future().sink(receiveCompletion: { result in\n                switch result {\n                case .failure:\n                    XCTAssert(false)\n                default:\n                    XCTAssert(true)\n                }\n            }, receiveValue: {\n                XCTAssertEqual($0, 1)\n                ex.fulfill()\n            })\n        } else {\n            ex.fulfill()\n        }\n        #else\n        ex.fulfill()\n        #endif\n        #else\n        ex.fulfill()\n        #endif\n\n        wait(for: [ex], timeout: 1)\n    }\n    \n    func testCombineGuaranteeValue() {\n        let ex = expectation(description: \"\")\n        #if swift(>=4.1)\n        #if canImport(Combine)\n        if #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) {\n            let promise = after(.milliseconds(100)).then(on: nil){ Guarantee.value(1) }\n            cancellable = promise.future().sink(receiveCompletion: { result in\n                switch result {\n                case .failure:\n                    XCTAssert(false)\n                default:\n                    XCTAssert(true)\n                }\n            }, receiveValue: {\n                XCTAssertEqual($0, 1)\n                ex.fulfill()\n            })\n        } else {\n            ex.fulfill()\n        }\n        #else\n        ex.fulfill()\n        #endif\n        #else\n        ex.fulfill()\n        #endif\n\n        wait(for: [ex], timeout: 1)\n    }\n    \n    func testCombinePromiseThrow() {\n        let ex = expectation(description: \"\")\n        #if swift(>=4.1)\n        #if canImport(Combine)\n        if #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) {\n            let promise = after(.milliseconds(100)).then(on: nil){ Promise(error: Error.dummy) }.then(on: nil){ Promise.value(1) }\n            cancellable = promise.future().sink(receiveCompletion: { result in\n                switch result {\n                case .failure(let error):\n                    switch error as? Error {\n                    case .dummy:\n                        XCTAssert(true)\n                    default:\n                        XCTAssert(false)\n                    }\n                default:\n                    XCTAssert(false)\n                }\n                ex.fulfill()\n            }, receiveValue: { _ in\n                XCTAssert(false)\n            })\n        } else {\n            ex.fulfill()\n        }\n        #else\n        ex.fulfill()\n        #endif\n        #else\n        ex.fulfill()\n        #endif\n\n        wait(for: [ex], timeout: 1)\n    }\n    \n    func testPromiseCombineValue() {\n        let ex = expectation(description: \"\")\n        #if swift(>=4.1)\n        #if canImport(Combine)\n        if #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) {\n            let promise = Future<Int, Error> { resolver in\n                resolver(.success(1))\n            }.delay(for: 5, scheduler: RunLoop.main).future().promise()\n            promise.done {\n                XCTAssertEqual($0, 1)\n                ex.fulfill()\n            }.catch { _ in\n                XCTAssert(false)\n                ex.fulfill()\n            }\n        } else {\n            ex.fulfill()\n        }\n        #else\n        ex.fulfill()\n        #endif\n        #else\n        ex.fulfill()\n        #endif\n\n        wait(for: [ex], timeout: 10)\n    }\n    \n    func testGuaranteeCombineValue() {\n        let ex = expectation(description: \"\")\n        #if swift(>=4.1)\n        #if canImport(Combine)\n        if #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) {\n            let guarantee = Future<Int, Never> { resolver in\n                resolver(.success(1))\n            }.delay(for: 5, scheduler: RunLoop.main).future().guarantee()\n            guarantee.done {\n                XCTAssertEqual($0, 1)\n                ex.fulfill()\n            }\n        } else {\n            ex.fulfill()\n        }\n        #else\n        ex.fulfill()\n        #endif\n        #else\n        ex.fulfill()\n        #endif\n\n        wait(for: [ex], timeout: 10)\n    }\n    \n    func testPromiseCombineThrows() {\n        let ex = expectation(description: \"\")\n        #if swift(>=4.1)\n        #if canImport(Combine)\n        if #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) {\n            let promise = Future<Int, Error> { resolver in\n                resolver(.failure(.dummy))\n            }.delay(for: 5, scheduler: RunLoop.main).map { _ in\n                100\n            }.future().promise()\n            promise.done { _ in\n                XCTAssert(false)\n                ex.fulfill()\n            }.catch { error in\n                switch error as? Error {\n                case .dummy:\n                    XCTAssert(true)\n                default:\n                    XCTAssert(false)\n                }\n                ex.fulfill()\n            }\n        } else {\n            ex.fulfill()\n        }\n        #else\n        ex.fulfill()\n        #endif\n        #else\n        ex.fulfill()\n        #endif\n\n        wait(for: [ex], timeout: 10)\n    }\n}\n\n#if swift(>=4.1)\n#if canImport(Combine)\n/// https://stackoverflow.com/a/60444607/2229783\n@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)\nprivate extension Publisher {\n    func future() -> Future<Output, Failure> {\n        return Future { promise in\n            var ticket: AnyCancellable? = nil\n            ticket = sink(\n                receiveCompletion: {\n                    ticket?.cancel()\n                    ticket = nil\n                    switch $0 {\n                    case .failure(let error):\n                        promise(.failure(error))\n                    case .finished:\n                        break\n                    }\n                },\n                receiveValue: {\n                    ticket?.cancel()\n                    ticket = nil\n                    promise(.success($0))\n                }\n            )\n        }\n    }\n}\n#endif\n#endif\n"
  },
  {
    "path": "Tests/CorePromise/DefaultDispatchQueueTests.swift",
    "content": "//\n//  PMKDefaultDispatchQueue.test.swift\n//  PromiseKit\n//\n//  Created by David Rodriguez on 4/14/16.\n//  Copyright © 2016 Max Howell. All rights reserved.\n//\n\nimport class Foundation.Thread\nimport PromiseKit\nimport Dispatch\nimport XCTest\n\nprivate enum Error: Swift.Error { case dummy }\n\n\nclass PMKDefaultDispatchQueueTest: XCTestCase {\n\n    let myQueue = DispatchQueue(label: \"myQueue\")\n\n    override func setUp() {\n        // can actually only set the default queue once\n        // - See: PMKSetDefaultDispatchQueue\n        conf.Q = (myQueue, myQueue)\n    }\n\n    override func tearDown() {\n        conf.Q = (.main, .main)\n    }\n\n    func testOverrodeDefaultThenQueue() {\n        let ex = expectation(description: \"resolving\")\n\n        Promise.value(1).then { _ -> Promise<Void> in\n            ex.fulfill()\n            XCTAssertFalse(Thread.isMainThread)\n            return Promise()\n        }.silenceWarning()\n\n        XCTAssertTrue(Thread.isMainThread)\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testOverrodeDefaultCatchQueue() {\n        let ex = expectation(description: \"resolving\")\n\n        Promise<Int>(error: Error.dummy).catch { _ in\n            ex.fulfill()\n            XCTAssertFalse(Thread.isMainThread)\n        }\n\n        XCTAssertTrue(Thread.isMainThread)\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testOverrodeDefaultAlwaysQueue() {\n        let ex = expectation(description: \"resolving\")\n\n        Promise.value(1).ensure {\n            ex.fulfill()\n            XCTAssertFalse(Thread.isMainThread)\n        }.silenceWarning()\n\n        XCTAssertTrue(Thread.isMainThread)\n\n        waitForExpectations(timeout: 1)\n    }\n}\n"
  },
  {
    "path": "Tests/CorePromise/ErrorTests.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass PMKErrorTests: XCTestCase {\n    func testCustomStringConvertible() {\n        XCTAssertNotNil(PMKError.invalidCallingConvention.errorDescription)\n        XCTAssertNotNil(PMKError.returnedSelf.errorDescription)\n        XCTAssertNotNil(PMKError.badInput.errorDescription)\n        XCTAssertNotNil(PMKError.cancelled.errorDescription)\n        XCTAssertNotNil(PMKError.compactMap(1, Int.self).errorDescription)\n        XCTAssertNotNil(PMKError.emptySequence.errorDescription)\n    }\n\n    func testCustomDebugStringConvertible() {\n        XCTAssertFalse(PMKError.invalidCallingConvention.debugDescription.isEmpty)\n        XCTAssertFalse(PMKError.returnedSelf.debugDescription.isEmpty)\n        XCTAssertNotNil(PMKError.badInput.debugDescription.isEmpty)\n        XCTAssertFalse(PMKError.cancelled.debugDescription.isEmpty)\n        XCTAssertFalse(PMKError.compactMap(1, Int.self).debugDescription.isEmpty)\n        XCTAssertFalse(PMKError.emptySequence.debugDescription.isEmpty)\n    }\n}\n"
  },
  {
    "path": "Tests/CorePromise/GuaranteeTests.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass GuaranteeTests: XCTestCase {\n    func testInit() {\n        let ex = expectation(description: \"\")\n        Guarantee { seal in\n            seal(1)\n        }.done {\n            XCTAssertEqual(1, $0)\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testMap() {\n        let ex = expectation(description: \"\")\n\n        Guarantee.value(1).map {\n            $0 * 2\n        }.done {\n            XCTAssertEqual(2, $0)\n            ex.fulfill()\n        }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testMapByKeyPath() {\n        let ex = expectation(description: \"\")\n\n        Guarantee.value(Person(name: \"Max\")).map(\\.name).done {\n            XCTAssertEqual(\"Max\", $0)\n            ex.fulfill()\n        }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testWait() {\n        XCTAssertEqual(after(.milliseconds(100)).map(on: nil){ 1 }.wait(), 1)\n    }\n\n    func testMapValues() {\n        let ex = expectation(description: \"\")\n\n        Guarantee.value([1, 2, 3])\n            .mapValues { $0 * 2 }\n            .done { values in\n                XCTAssertEqual([2, 4, 6], values)\n                ex.fulfill()\n            }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testMapValuesByKeyPath() {\n        let ex = expectation(description: \"\")\n\n        Guarantee.value([Person(name: \"Max\"), Person(name: \"Roman\"), Person(name: \"John\")])\n            .mapValues(\\.name)\n            .done { values in\n                XCTAssertEqual([\"Max\", \"Roman\", \"John\"], values)\n                ex.fulfill()\n            }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testFlatMapValues() {\n        let ex = expectation(description: \"\")\n\n        Guarantee.value([1, 2, 3])\n            .flatMapValues { [$0, $0] }\n            .done { values in\n                XCTAssertEqual([1, 1, 2, 2, 3, 3], values)\n                ex.fulfill()\n            }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testCompactMapValues() {\n        let ex = expectation(description: \"\")\n\n        Guarantee.value([\"1\",\"2\",\"a\",\"3\"])\n            .compactMapValues { Int($0) }\n            .done { values in\n                XCTAssertEqual([1, 2, 3], values)\n                ex.fulfill()\n            }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testCompactMapValuesByKeyPath() {\n        let ex = expectation(description: \"\")\n\n        Guarantee.value([Person(name: \"Max\"), Person(name: \"Roman\", age: 26), Person(name: \"John\", age: 23)])\n            .compactMapValues(\\.age)\n            .done { values in\n                XCTAssertEqual([26, 23], values)\n                ex.fulfill()\n            }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testThenMap() {\n\n        let ex = expectation(description: \"\")\n\n        Guarantee.value([1, 2, 3])\n            .thenMap { Guarantee.value($0 * 2) }\n            .done { values in\n                XCTAssertEqual([2, 4, 6], values)\n                ex.fulfill()\n            }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testThenFlatMap() {\n\n        let ex = expectation(description: \"\")\n\n        Guarantee.value([1, 2, 3])\n            .thenFlatMap { Guarantee.value([$0, $0]) }\n            .done { values in\n                XCTAssertEqual([1, 1, 2, 2, 3, 3], values)\n                ex.fulfill()\n            }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testFilterValues() {\n\n        let ex = expectation(description: \"\")\n\n        Guarantee.value([1, 2, 3])\n            .filterValues { $0 > 1 }\n            .done { values in\n                XCTAssertEqual([2, 3], values)\n                ex.fulfill()\n            }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testFilterValuesByKeyPath() {\n\n        let ex = expectation(description: \"\")\n\n        Guarantee.value([Person(name: \"Max\"), Person(name: \"Roman\", age: 26, isStudent: false), Person(name: \"John\", age: 23, isStudent: true)])\n            .filterValues(\\.isStudent)\n            .done { values in\n                XCTAssertEqual([Person(name: \"John\", age: 23, isStudent: true)], values)\n                ex.fulfill()\n            }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testSorted() {\n\n        let ex = expectation(description: \"\")\n\n        Guarantee.value([5, 2, 3, 4, 1])\n            .sortedValues()\n            .done { values in\n                XCTAssertEqual([1, 2, 3, 4, 5], values)\n                ex.fulfill()\n            }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testSortedBy() {\n\n        let ex = expectation(description: \"\")\n\n        Guarantee.value([5, 2, 3, 4, 1])\n            .sortedValues { $0 > $1 }\n            .done { values in\n                XCTAssertEqual([5, 4, 3, 2, 1], values)\n                ex.fulfill()\n            }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    #if swift(>=3.1)\n    func testNoAmbiguityForValue() {\n        let ex = expectation(description: \"\")\n        let a = Guarantee<Void>.value\n        let b = Guarantee<Void>.value(Void())\n        let c = Guarantee<Void>.value(())\n        when(fulfilled: a, b, c).done {\n            ex.fulfill()\n        }.cauterize()\n        wait(for: [ex], timeout: 10)\n    }\n    #endif\n}\n"
  },
  {
    "path": "Tests/CorePromise/HangTests.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass HangTests: XCTestCase {\n    func test() {\n        let ex = expectation(description: \"block executed\")\n        do {\n            let value = try hang(after(seconds: 0.02).then { _ -> Promise<Int> in\n                ex.fulfill()\n                return .value(1)\n            })\n            XCTAssertEqual(value, 1)\n        } catch {\n            XCTFail(\"Unexpected error\")\n        }\n        waitForExpectations(timeout: 0)\n    }\n\n    enum Error: Swift.Error {\n        case test\n    }\n\n    func testError() {\n        var value = 0\n        do {\n            _ = try hang(after(seconds: 0.02).done {\n                value = 1\n                throw Error.test\n            })\n            XCTAssertEqual(value, 1)\n        } catch Error.test {\n            return\n        } catch {\n            XCTFail(\"Unexpected error (expected Error.test)\")\n        }\n        XCTFail(\"Expected error but no error was thrown\")\n    }\n}\n"
  },
  {
    "path": "Tests/CorePromise/LoggingTests.swift",
    "content": "@testable import PromiseKit\nimport Dispatch\nimport XCTest\n#if canImport(Android)\nimport Android\n#endif\n\nclass LoggingTests: XCTestCase {\n    /**\n     The test should emit the following log messages:\n     \n     PromiseKit: warning: `wait()` called on main thread!\n     PromiseKit: warning: pending promise deallocated\n     PromiseKit:cauterized-error: purposes\n     This is an error message\n    */\n    func testLogging() {\n        \n        var logOutput: String? = nil\n        \n        enum ForTesting: Error {\n            case purposes\n        }\n        \n        // Test Logging to Console, the default behavior\n        conf.logHandler(.waitOnMainThread)\n        conf.logHandler(.pendingPromiseDeallocated)\n        conf.logHandler(.pendingGuaranteeDeallocated)\n        conf.logHandler(.cauterized(ForTesting.purposes))\n        XCTAssertNil(logOutput)\n\n        // Now test no logging\n        conf.logHandler = { event in }\n        conf.logHandler(.waitOnMainThread)\n        conf.logHandler(.pendingPromiseDeallocated)\n        conf.logHandler(.cauterized(ForTesting.purposes))\n        XCTAssertNil(logOutput)\n\n        conf.logHandler =  { event in\n            switch event {\n            case .waitOnMainThread, .pendingPromiseDeallocated, .pendingGuaranteeDeallocated:\n                logOutput = \"\\(event)\"\n            case .cauterized:\n                // Using an enum with associated value does not convert to a string properly in\n                // earlier versions of swift\n                logOutput = \"cauterized\"\n            }\n        }\n        conf.logHandler(.waitOnMainThread)\n        XCTAssertEqual(logOutput!, \"waitOnMainThread\")\n        logOutput = nil\n        conf.logHandler(.pendingPromiseDeallocated)\n        XCTAssertEqual(logOutput!, \"pendingPromiseDeallocated\")\n        logOutput = nil\n        conf.logHandler(.cauterized(ForTesting.purposes))\n        XCTAssertEqual(logOutput!, \"cauterized\")\n    }\n\n    // Verify waiting on main thread in Promise is logged\n    func testPromiseWaitOnMainThreadLogged() throws {\n        \n        enum ForTesting: Error {\n            case purposes\n        }\n        \n        var logOutput: String? = nil\n        conf.logHandler = { event in\n            logOutput = \"\\(event)\"\n        }\n        let promiseResolver = Promise<String>.pending()\n        let workQueue = DispatchQueue(label: \"worker\")\n        workQueue.async {\n            promiseResolver.resolver.fulfill (\"PromiseFulfilled\")\n        }\n        let promisedString = try promiseResolver.promise.wait()\n        XCTAssertEqual(\"PromiseFulfilled\", promisedString)\n        XCTAssertEqual(logOutput!, \"waitOnMainThread\")\n    }\n    \n    // Verify Promise.cauterize() is logged\n    func testCauterizeIsLogged() {\n        \n        enum ForTesting: Error {\n            case purposes\n        }\n\n        var logOutput: String? = nil\n        conf.logHandler = { event in\n            switch event {\n            case .waitOnMainThread, .pendingPromiseDeallocated, .pendingGuaranteeDeallocated:\n                logOutput = \"\\(event)\"\n            case .cauterized:\n                // Using an enum with associated value does not convert to a string properly in\n                // earlier versions of swift\n                logOutput = \"cauterized\"\n            }\n        }\n        func createPromise() -> Promise<String> {\n            let promiseResolver = Promise<String>.pending()\n            \n            let queue = DispatchQueue(label: \"workQueue\")\n            queue.async {\n                promiseResolver.resolver.reject(ForTesting.purposes)\n            }\n            return promiseResolver.promise\n        }\n        var ex = expectation(description: \"cauterize\")\n        firstly {\n            createPromise()\n        }.ensure {\n            ex.fulfill()\n        }.cauterize()\n        waitForExpectations(timeout: 1)\n        ex = expectation(description: \"read\")\n        let readQueue = DispatchQueue(label: \"readQueue\")\n        readQueue.async {\n            var outputSet = false\n            while !outputSet {\n                if let logOutput = logOutput {\n                    XCTAssertEqual(logOutput, \"cauterized\")\n                    outputSet = true\n                    ex.fulfill()\n                }\n                if !outputSet {\n                    usleep(10000)\n                }\n            }\n        }\n        waitForExpectations(timeout: 1)\n    }\n\n    // Verify waiting on main thread in Guarantee is logged\n    func testGuaranteeWaitOnMainThreadLogged() {\n        \n        enum ForTesting: Error {\n            case purposes\n        }\n        \n        var logOutput: String? = nil\n        conf.logHandler = { event in\n            switch event {\n            case .waitOnMainThread, .pendingPromiseDeallocated, .pendingGuaranteeDeallocated:\n                logOutput = \"\\(event)\"\n            case .cauterized:\n                // Using an enum with associated value does not convert to a string properly in\n                // earlier versions of swift\n                logOutput = \"cauterized\"\n            }\n        }\n        let guaranteeResolve = Guarantee<String>.pending()\n        let workQueue = DispatchQueue(label: \"worker\")\n        workQueue.async {\n            guaranteeResolve.resolve(\"GuaranteeFulfilled\")\n        }\n        let guaranteedString = guaranteeResolve.guarantee.wait()\n        XCTAssertEqual(\"GuaranteeFulfilled\", guaranteedString)\n        XCTAssertEqual(logOutput!, \"waitOnMainThread\")\n    }\n    \n    // Verify pendingPromiseDeallocated is logged\n    func testPendingPromiseDeallocatedIsLogged() {\n        \n        var logOutput: String? = nil\n        conf.logHandler = { event in\n            switch event {\n            case .waitOnMainThread, .pendingPromiseDeallocated, .pendingGuaranteeDeallocated:\n                logOutput = \"\\(event)\"\n            case .cauterized:\n                // Using an enum with associated value does not convert to a string properly in\n                // earlier versions of swift\n                logOutput = \"cauterized\"\n            }\n        }\n        do {\n            let _ = Promise<Int>.pending()\n        }\n        XCTAssertEqual (\"pendingPromiseDeallocated\", logOutput!)\n    }\n    \n    // Verify pendingGuaranteeDeallocated is logged\n    func testPendingGuaranteeDeallocatedIsLogged() {\n        \n        var logOutput: String? = nil\n        let loggingClosure: (PromiseKit.LogEvent) -> Void = { event in\n            switch event {\n            case .waitOnMainThread, .pendingPromiseDeallocated, .pendingGuaranteeDeallocated:\n                logOutput = \"\\(event)\"\n            case .cauterized:\n                // Using an enum with associated value does not convert to a string properly in\n                // earlier versions of swift\n                logOutput = \"cauterized\"\n            }\n        }\n        conf.logHandler = loggingClosure\n        do {\n            let _ = Guarantee<Int>.pending()\n        }\n        XCTAssertEqual (\"pendingGuaranteeDeallocated\", logOutput!)\n    }\n    \n    //TODO Verify pending promise deallocation is logged\n}\n"
  },
  {
    "path": "Tests/CorePromise/PromiseTests.swift",
    "content": "import PromiseKit\nimport Dispatch\nimport XCTest\n\nclass PromiseTests: XCTestCase {\n    func testIsPending() {\n        XCTAssertTrue(Promise<Void>.pending().promise.isPending)\n        XCTAssertFalse(Promise().isPending)\n        XCTAssertFalse(Promise<Void>(error: Error.dummy).isPending)\n    }\n\n    func testIsResolved() {\n        XCTAssertFalse(Promise<Void>.pending().promise.isResolved)\n        XCTAssertTrue(Promise().isResolved)\n        XCTAssertTrue(Promise<Void>(error: Error.dummy).isResolved)\n    }\n\n    func testIsFulfilled() {\n        XCTAssertFalse(Promise<Void>.pending().promise.isFulfilled)\n        XCTAssertTrue(Promise().isFulfilled)\n        XCTAssertFalse(Promise<Void>(error: Error.dummy).isFulfilled)\n    }\n\n    func testIsRejected() {\n        XCTAssertFalse(Promise<Void>.pending().promise.isRejected)\n        XCTAssertTrue(Promise<Void>(error: Error.dummy).isRejected)\n        XCTAssertFalse(Promise().isRejected)\n    }\n\n    @available(macOS 10.10, iOS 2.0, tvOS 10.0, watchOS 2.0, *)\n    func testDispatchQueueAsyncExtensionReturnsPromise() {\n        let ex = expectation(description: \"\")\n\n        DispatchQueue.global().async(.promise) { () -> Int in\n            XCTAssertFalse(Thread.isMainThread)\n            return 1\n        }.done { one in\n            XCTAssertEqual(one, 1)\n            ex.fulfill()\n        }\n\n        waitForExpectations(timeout: 1)\n    }\n\n    @available(macOS 10.10, iOS 2.0, tvOS 10.0, watchOS 2.0, *)\n    func testDispatchQueueAsyncExtensionCanThrowInBody() {\n        let ex = expectation(description: \"\")\n\n        DispatchQueue.global().async(.promise) { () -> Int in\n            throw Error.dummy\n        }.done { _ in\n            XCTFail()\n        }.catch { _ in\n            ex.fulfill()\n        }\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testCustomStringConvertible() {\n        XCTAssertEqual(Promise<Int>.pending().promise.debugDescription, \"Promise<Int>.pending(handlers: 0)\")\n        XCTAssertEqual(Promise().debugDescription, \"Promise<()>.fulfilled(())\")\n        XCTAssertEqual(Promise<String>(error: Error.dummy).debugDescription, \"Promise<String>.rejected(Error.dummy)\")\n\n        XCTAssertEqual(\"\\(Promise<Int>.pending().promise)\", \"Promise(…Int)\")\n        XCTAssertEqual(\"\\(Promise.value(3))\", \"Promise(3)\")\n        XCTAssertEqual(\"\\(Promise<Void>(error: Error.dummy))\", \"Promise(dummy)\")\n    }\n\n    func testCannotFulfillWithError() {\n\n        // sadly this test proves the opposite :(\n        // left here so maybe one day we can prevent instantiation of `Promise<Error>`\n\n        _ = Promise { seal in\n            seal.fulfill(Error.dummy)\n        }\n\n        _ = Promise<Error>.pending()\n\n        _ = Promise.value(Error.dummy)\n\n        _ = Promise().map { Error.dummy }\n    }\n\n#if swift(>=3.1)\n    func testCanMakeVoidPromise() {\n        _ = Promise()\n        _ = Guarantee()\n    }\n#endif\n\n    enum Error: Swift.Error {\n        case dummy\n    }\n\n    func testThrowInInitializer() {\n        let p = Promise<Void> { _ in\n            throw Error.dummy\n        }\n        XCTAssertTrue(p.isRejected)\n        guard let err = p.error, case Error.dummy = err else { return XCTFail() }\n    }\n\n    func testThrowInFirstly() {\n        let ex = expectation(description: \"\")\n\n        firstly { () -> Promise<Int> in\n            throw Error.dummy\n        }.catch {\n            XCTAssertEqual($0 as? Error, Error.dummy)\n            ex.fulfill()\n        }\n\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testWait() throws {\n        let p = after(.milliseconds(100)).then(on: nil){ Promise.value(1) }\n        XCTAssertEqual(try p.wait(), 1)\n\n        do {\n            let p = after(.milliseconds(100)).map(on: nil){ throw Error.dummy }\n            try p.wait()\n            XCTFail()\n        } catch {\n            XCTAssertEqual(error as? Error, Error.dummy)\n        }\n    }\n\n    func testPipeForResolved() {\n        let ex = expectation(description: \"\")\n        Promise.value(1).done {\n            XCTAssertEqual(1, $0)\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    #if swift(>=3.1)\n    func testNoAmbiguityForValue() {\n        let ex = expectation(description: \"\")\n        let a = Promise<Void>.value\n        let b = Promise<Void>.value(Void())\n        let c = Promise<Void>.value(())\n        when(fulfilled: a, b, c).done {\n            ex.fulfill()\n        }.cauterize()\n        wait(for: [ex], timeout: 10)\n    }\n    #endif\n}\n"
  },
  {
    "path": "Tests/CorePromise/RaceTests.swift",
    "content": "import XCTest\nimport PromiseKit\n\nclass RaceTests: XCTestCase {\n    func test1() {\n        let ex = expectation(description: \"\")\n        race(after(.milliseconds(10)).then{ Promise.value(1) }, after(seconds: 1).map{ 2 }).done { index in\n            XCTAssertEqual(index, 1)\n            ex.fulfill()\n        }.silenceWarning()\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n    \n    func test2() {\n        let ex = expectation(description: \"\")\n        race(after(seconds: 1).map{ 1 }, after(.milliseconds(10)).map{ 2 }).done { index in\n            XCTAssertEqual(index, 2)\n            ex.fulfill()\n        }\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n    func test1Array() {\n        let ex = expectation(description: \"\")\n        let promises = [after(.milliseconds(10)).map{ 1 }, after(seconds: 1).map{ 2 }]\n        race(promises).done { index in\n            XCTAssertEqual(index, 1)\n            ex.fulfill()\n        }.silenceWarning()\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n    \n    func test2Array() {\n        let ex = expectation(description: \"\")\n        race(after(seconds: 1).map{ 1 }, after(.milliseconds(10)).map{ 2 }).done { index in\n            XCTAssertEqual(index, 2)\n            ex.fulfill()\n        }\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n    func testEmptyArray() {\n        let ex = expectation(description: \"\")\n        let empty = [Promise<Int>]()\n        race(empty).catch {\n            guard case PMKError.badInput = $0 else { return XCTFail() }\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testFulfilled() {\n        enum Error: Swift.Error { case test1, test2, test3 }\n        let ex = expectation(description: \"\")\n        let promises: [Promise<Int>] = [after(seconds: 1).map { _ in throw Error.test1 }, after(seconds: 2).map { _ in throw Error.test2 }, after(seconds: 5).map { 1 }, after(seconds: 4).map { 2 }, after(seconds: 3).map { _ in throw Error.test3 }]\n        race(fulfilled: promises).done {\n            XCTAssertEqual($0, 2)\n            ex.fulfill()\n        }.catch { _ in\n            XCTFail()\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testFulfilledEmptyArray() {\n        let ex = expectation(description: \"\")\n        let empty = [Promise<Int>]()\n        race(fulfilled: empty).catch {\n            guard case PMKError.badInput = $0 else { return XCTFail() }\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testFulfilledWithNoWinner() {\n        enum Error: Swift.Error { case test1, test2 }\n        let ex = expectation(description: \"\")\n        let promises: [Promise<Int>] = [\n            after(seconds: 1).map { _ in throw Error.test1 },\n            after(seconds: 2).map { _ in throw Error.test2 }\n        ]\n        race(fulfilled: promises).done { _ in\n            XCTFail(\"Done with error\")\n            ex.fulfill()\n        }.catch {\n            guard let pmkError = $0 as? PMKError else { return XCTFail(\"error is not PMKError\") }\n            guard case .noWinner = pmkError else { return XCTFail(\"error is not .noWinner\") }\n            guard pmkError.debugDescription == \"All thenables passed to race(fulfilled:) were rejected\" else { return XCTFail(\"Not all thenables passed to race(fulfilled:) were rejected\") }\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n}\n"
  },
  {
    "path": "Tests/CorePromise/RegressionTests.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass RegressionTests: XCTestCase {\n    func testReturningPreviousPromiseWorks() {\n\n        // regression test because we were doing this wrong\n        // in our A+ tests implementation for spec: 2.3.1\n\n        do {\n            let promise1 = Promise()\n            let promise2 = promise1.then(on: nil) { promise1 }\n            promise2.catch(on: nil) { _ in XCTFail() }\n        }\n        do {\n            enum Error: Swift.Error { case dummy }\n\n            let promise1 = Promise<Void>(error: Error.dummy)\n            let promise2 = promise1.recover(on: nil) { _ in promise1 }\n            promise2.catch(on: nil) { err in\n                if case PMKError.returnedSelf = err {\n                    XCTFail()\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/CorePromise/ResolverTests.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass WrapTests: XCTestCase {\n    fileprivate class KittenFetcher {\n        let value: Int?\n        let error: Error?\n\n        init(value: Int?, error: Error?) {\n            self.value = value\n            self.error = error\n        }\n\n        func fetchWithCompletionBlock(block: @escaping(Int?, Error?) -> Void) {\n            after(.milliseconds(20)).done {\n                block(self.value, self.error)\n            }\n        }\n\n        func fetchWithCompletionBlock2(block: @escaping(Error?, Int?) -> Void) {\n            after(.milliseconds(20)).done {\n                block(self.error, self.value)\n            }\n        }\n\n        func fetchWithCompletionBlock3(block: @escaping(Int, Error?) -> Void) {\n            after(.milliseconds(20)).done {\n                block(self.value ?? -99, self.error)\n            }\n        }\n\n        func fetchWithCompletionBlock4(block: @escaping(Error?) -> Void) {\n            after(.milliseconds(20)).done {\n                block(self.error)\n            }\n        }\n\n#if swift(>=5.0)\n        func fetchWithCompletionBlock5(block: @escaping(Swift.Result<Int, Error>) -> Void) {\n            after(.milliseconds(20)).done {\n                if let value = self.value {\n                    block(.success(value))\n                } else {\n                    block(.failure(self.error!))\n                }\n            }\n        }\n#endif\n    }\n\n    func testSuccess() {\n        let ex = expectation(description: \"\")\n        let kittenFetcher = KittenFetcher(value: 2, error: nil)\n        Promise { seal in\n            kittenFetcher.fetchWithCompletionBlock(block: seal.resolve)\n        }.done {\n            XCTAssertEqual($0, 2)\n            ex.fulfill()\n        }.silenceWarning()\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testError() {\n        let ex = expectation(description: \"\")\n\n        let kittenFetcher = KittenFetcher(value: nil, error: Error.test)\n        Promise { seal in\n            kittenFetcher.fetchWithCompletionBlock(block: seal.resolve)\n        }.catch { error in\n            defer { ex.fulfill() }\n            guard case Error.test = error else {\n                return XCTFail()\n            }\n        }\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testInvalidCallingConvention() {\n        let ex = expectation(description: \"\")\n\n        let kittenFetcher = KittenFetcher(value: nil, error: nil)\n        Promise { seal in\n            kittenFetcher.fetchWithCompletionBlock(block: seal.resolve)\n        }.catch { error in\n            defer { ex.fulfill() }\n            guard case PMKError.invalidCallingConvention = error else {\n                return XCTFail()\n            }\n        }\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testInvertedCallingConvention() {\n        let ex = expectation(description: \"\")\n        let kittenFetcher = KittenFetcher(value: 2, error: nil)\n        Promise { seal in\n            kittenFetcher.fetchWithCompletionBlock2(block: seal.resolve)\n        }.done {\n            XCTAssertEqual($0, 2)\n            ex.fulfill()\n        }.silenceWarning()\n\n        waitForExpectations(timeout: 1)\n\n    }\n\n    func testNonOptionalFirstParameter() {\n        let ex1 = expectation(description: \"\")\n        let kf1 = KittenFetcher(value: 2, error: nil)\n        Promise { seal in\n            kf1.fetchWithCompletionBlock3(block: seal.resolve)\n        }.done {\n            XCTAssertEqual($0, 2)\n            ex1.fulfill()\n        }.silenceWarning()\n\n        let ex2 = expectation(description: \"\")\n        let kf2 = KittenFetcher(value: -100, error: Error.test)\n        Promise { seal in\n            kf2.fetchWithCompletionBlock3(block: seal.resolve)\n        }.catch { _ in ex2.fulfill() }\n\n        wait(for: [ex1, ex2] ,timeout: 1)\n    }\n\n#if swift(>=3.1)\n    func testVoidCompletionValue() {\n        let ex1 = expectation(description: \"\")\n        let kf1 = KittenFetcher(value: nil, error: nil)\n        Promise { seal in\n            kf1.fetchWithCompletionBlock4(block: seal.resolve)\n        }.done(ex1.fulfill).silenceWarning()\n\n        let ex2 = expectation(description: \"\")\n        let kf2 = KittenFetcher(value: nil, error: Error.test)\n        Promise { seal in\n            kf2.fetchWithCompletionBlock4(block: seal.resolve)\n        }.catch { _ in ex2.fulfill() }\n\n        wait(for: [ex1, ex2], timeout: 1)\n    }\n#endif\n\n    func testSwiftResultSuccess() {\n    #if swift(>=5.0)\n        let ex = expectation(description: \"\")\n        let kittenFetcher = KittenFetcher(value: 2, error: nil)\n        Promise { seal in\n            kittenFetcher.fetchWithCompletionBlock5(block: seal.resolve)\n        }.done {\n            XCTAssertEqual($0, 2)\n            ex.fulfill()\n        }.silenceWarning()\n\n        waitForExpectations(timeout: 1)\n    #endif\n    }\n\n    func testSwiftResultError() {\n    #if swift(>=5.0)\n        let ex = expectation(description: \"\")\n\n        let kittenFetcher = KittenFetcher(value: nil, error: Error.test)\n        Promise { seal in\n            kittenFetcher.fetchWithCompletionBlock5(block: seal.resolve)\n        }.catch { error in\n            defer { ex.fulfill() }\n            guard case Error.test = error else {\n                return XCTFail()\n            }\n        }\n\n        waitForExpectations(timeout: 1)\n    #endif\n    }\n\n    func testIsFulfilled() {\n        XCTAssertTrue(Promise.value(()).result?.isFulfilled ?? false)\n        XCTAssertFalse(Promise<Int>(error: Error.test).result?.isFulfilled ?? true)\n    }\n\n    func testPendingPromiseDeallocated() {\n\n        // NOTE this doesn't seem to register the `deinit` as covered :(\n        // BUT putting a breakpoint in the deinit CLEARLY shows it getting covered…\n\n        class Foo {\n            let p = Promise<Void>.pending()\n            var ex: XCTestExpectation!\n\n            deinit {\n                after(.milliseconds(100)).done(ex.fulfill)\n            }\n        }\n\n        let ex = expectation(description: \"\")\n        do {\n            // for code coverage report for `Resolver.deinit` warning\n            let foo = Foo()\n            foo.ex = ex\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testVoidResolverFulfillAmbiguity() {\n    #if !swift(>=5) && swift(>=4.1) || swift(>=3.3) && !swift(>=4.0)\n    // ^^ this doesn’t work with Swift < 3.3 for some reason\n    // ^^ this doesn’t work with Swift 5.0-beta1 for some reason\n\n        // reference: https://github.com/mxcl/PromiseKit/issues/990\n\n        func foo(success: () -> Void, failure: (Error) -> Void) {\n            success()\n        }\n\n        func bar() -> Promise<Void> {\n            return Promise<Void> { (seal: Resolver<Void>) in\n                foo(success: seal.fulfill, failure: seal.reject)\n            }\n        }\n\n        let ex = expectation(description: \"\")\n        bar().done(ex.fulfill).cauterize()\n        wait(for: [ex], timeout: 10)\n    #endif\n    }\n}\n\nprivate enum Error: Swift.Error {\n    case test\n}\n"
  },
  {
    "path": "Tests/CorePromise/StressTests.swift",
    "content": "import PromiseKit\nimport Dispatch\nimport XCTest\n\nclass StressTests: XCTestCase {\n    func testThenDataRace() {\n        let e1 = expectation(description: \"\")\n\n        //will crash if then doesn't protect handlers\n        stressDataRace(expectation: e1, stressFunction: { promise in\n            promise.done { s in\n                XCTAssertEqual(\"ok\", s)\n                return\n            }.silenceWarning()\n        }, fulfill: { \"ok\" })\n\n        waitForExpectations(timeout: 10, handler: nil)\n    }\n\n    @available(macOS 10.10, iOS 2.0, tvOS 10.0, watchOS 2.0, *)\n    func testThensAreSequentialForLongTime() {\n        var values = [Int]()\n        let ex = expectation(description: \"\")\n        var promise = DispatchQueue.global().async(.promise){ 0 }\n        let N = 1000\n        for x in 1..<N {\n            promise = promise.then { y -> Guarantee<Int> in\n                values.append(y)\n                XCTAssertEqual(x - 1, y)\n                return DispatchQueue.global().async(.promise) { x }\n            }\n        }\n        promise.done { x in\n            values.append(x)\n            XCTAssertEqual(values, (0..<N).map{ $0 })\n            ex.fulfill()\n        }\n        waitForExpectations(timeout: 10, handler: nil)\n    }\n\n    func testZalgoDataRace() {\n        let e1 = expectation(description: \"\")\n\n        //will crash if zalgo doesn't protect handlers\n        stressDataRace(expectation: e1, stressFunction: { promise in\n            promise.done(on: nil) { s in\n                XCTAssertEqual(\"ok\", s)\n            }.silenceWarning()\n        }, fulfill: {\n            return \"ok\"\n        })\n\n        waitForExpectations(timeout: 10, handler: nil)\n    }\n}\n\nprivate enum Error: Swift.Error {\n    case Dummy\n}\n\nprivate func stressDataRace<T: Equatable>(expectation e1: XCTestExpectation, iterations: Int = 1000, stressFactor: Int = 10, stressFunction: @escaping (Promise<T>) -> Void, fulfill f: @escaping () -> T) {\n    let group = DispatchGroup()\n    let queue = DispatchQueue(label: \"the.domain.of.Zalgo\", attributes: .concurrent)\n\n    for _ in 0..<iterations {\n        let (promise, seal) = Promise<T>.pending()\n\n        DispatchQueue.concurrentPerform(iterations: stressFactor) { n in\n            stressFunction(promise)\n        }\n\n        queue.async(group: group) {\n            seal.fulfill(f())\n        }\n    }\n\n    group.notify(queue: queue, execute: e1.fulfill)\n}\n"
  },
  {
    "path": "Tests/CorePromise/ThenableTests.swift",
    "content": "import PromiseKit\nimport Dispatch\nimport XCTest\n\nstruct Person: Equatable {\n    let name: String\n    let age: Int?\n    let isStudent: Bool\n\n    init(\n        name: String = \"\",\n        age: Int? = nil,\n        isStudent: Bool = false\n    ) {\n        self.name = name\n        self.age = age\n        self.isStudent = isStudent\n    }\n}\n\nclass ThenableTests: XCTestCase {\n    func testGet() {\n        let ex1 = expectation(description: \"\")\n        let ex2 = expectation(description: \"\")\n        Promise.value(1).get {\n            XCTAssertEqual($0, 1)\n            ex1.fulfill()\n        }.done {\n            XCTAssertEqual($0, 1)\n            ex2.fulfill()\n        }.silenceWarning()\n        wait(for: [ex1, ex2], timeout: 10)\n    }\n\n    func testMap() {\n        let ex = expectation(description: \"\")\n        Promise.value(1).map {\n            $0 * 2\n        }.done {\n            XCTAssertEqual($0, 2)\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testMapByKeyPath() {\n        let ex = expectation(description: \"\")\n        Promise.value(Person(name: \"Max\")).map(\\.name).done {\n            XCTAssertEqual($0, \"Max\")\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testCompactMap() {\n        let ex = expectation(description: \"\")\n        Promise.value(1.0).compactMap {\n            Int($0)\n        }.done {\n            XCTAssertEqual($0, 1)\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testCompactMapThrows() {\n\n        enum E: Error { case dummy }\n\n        let ex = expectation(description: \"\")\n        Promise.value(\"a\").compactMap { x -> Int in\n            throw E.dummy\n        }.catch {\n            if case E.dummy = $0 {} else {\n                XCTFail()\n            }\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testRejectedPromiseCompactMap() {\n\n        enum E: Error { case dummy }\n\n        let ex = expectation(description: \"\")\n        Promise(error: E.dummy).compactMap {\n            Int($0)\n        }.catch {\n            if case E.dummy = $0 {} else {\n                XCTFail()\n            }\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testPMKErrorCompactMap() {\n        let ex = expectation(description: \"\")\n        Promise.value(\"a\").compactMap {\n            Int($0)\n        }.catch {\n            if case PMKError.compactMap = $0 {} else {\n                XCTFail()\n            }\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testCompactMapByKeyPath() {\n        let ex = expectation(description: \"\")\n        Promise.value(Person(name: \"Roman\", age: 26)).compactMap(\\.age).done {\n            XCTAssertEqual($0, 26)\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testMapValues() {\n        let ex = expectation(description: \"\")\n        Promise.value([14, 20, 45]).mapValues {\n            $0 * 2\n        }.done {\n            XCTAssertEqual([28, 40, 90], $0)\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testMapValuesByKeyPath() {\n        let ex = expectation(description: \"\")\n        Promise.value([Person(name: \"Max\"), Person(name: \"Roman\"), Person(name: \"John\")]).mapValues(\\.name).done {\n            XCTAssertEqual([\"Max\", \"Roman\", \"John\"], $0)\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testCompactMapValues() {\n        let ex = expectation(description: \"\")\n        Promise.value([\"1\",\"2\",\"a\",\"4\"]).compactMapValues {\n            Int($0)\n        }.done {\n            XCTAssertEqual([1,2,4], $0)\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testCompactMapValuesByKeyPath() {\n        let ex = expectation(description: \"\")\n        Promise.value([Person(name: \"Max\"), Person(name: \"Roman\", age: 26), Person(name: \"John\", age: 23)]).compactMapValues(\\.age).done {\n            XCTAssertEqual([26, 23], $0)\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testThenMap() {\n        let ex = expectation(description: \"\")\n        Promise.value([1,2,3,4]).thenMap {\n            Promise.value($0)\n        }.done {\n            XCTAssertEqual([1,2,3,4], $0)\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testThenFlatMap() {\n        let ex = expectation(description: \"\")\n        Promise.value([1,2,3,4]).thenFlatMap {\n            Promise.value([$0, $0])\n        }.done {\n            XCTAssertEqual([1,1,2,2,3,3,4,4], $0)\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testFilterValues() {\n        let ex = expectation(description: \"\")\n        Promise.value([Person(name: \"Max\"), Person(name: \"Roman\", age: 26, isStudent: false), Person(name: \"John\", age: 23, isStudent: true)]).filterValues {\n            $0.isStudent\n        }.done {\n            XCTAssertEqual([Person(name: \"John\", age: 23, isStudent: true)], $0)\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testFilterValuesByKeyPath() {\n        let ex = expectation(description: \"\")\n        Promise.value([Person(name: \"Max\"), Person(name: \"Roman\", age: 26, isStudent: false), Person(name: \"John\", age: 23, isStudent: true)]).filterValues(\\.isStudent).done {\n            XCTAssertEqual([Person(name: \"John\", age: 23, isStudent: true)], $0)\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testLastValueForEmpty() {\n        let values = [String]()\n        XCTAssertTrue(Promise.value(values).lastValue.isRejected)\n    }\n\n    func testFirstValueForEmpty() {\n        let values = [String]()\n        XCTAssertTrue(Promise.value(values).firstValue.isRejected)\n    }\n\n    func testThenOffRejected() {\n        // surprisingly missing in our CI, mainly due to\n        // extensive use of `done` in A+ tests since PMK 5\n\n        let ex = expectation(description: \"\")\n        Promise<Int>(error: PMKError.badInput).then { x -> Promise<Int> in\n            XCTFail()\n            return .value(x)\n        }.catch { _ in\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testBarrier() {\n        let ex = expectation(description: \"\")\n        let q = DispatchQueue(label: \"\\(#file):\\(#line)\", attributes: .concurrent)\n        Promise.value(1).done(on: q, flags: .barrier) {\n            XCTAssertEqual($0, 1)\n            dispatchPrecondition(condition: .onQueueAsBarrier(q))\n            ex.fulfill()\n        }.catch { _ in\n            XCTFail()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testDispatchFlagsSyntax() {\n        let ex = expectation(description: \"\")\n        let q = DispatchQueue(label: \"\\(#file):\\(#line)\", attributes: .concurrent)\n        Promise.value(1).done(on: q, flags: [.barrier, .inheritQoS]) {\n            XCTAssertEqual($0, 1)\n            dispatchPrecondition(condition: .onQueueAsBarrier(q))\n            ex.fulfill()\n            }.catch { _ in\n                XCTFail()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n}\n"
  },
  {
    "path": "Tests/CorePromise/Utilities.swift",
    "content": "import PromiseKit\n\nextension Promise {\n    func silenceWarning() {}\n}\n\n#if os(Linux) || os(Android)\nimport func CoreFoundation._CFIsMainThread\n\nextension Thread {\n    // `isMainThread` is not implemented yet in swift-corelibs-foundation.\n    static var isMainThread: Bool {\n        return _CFIsMainThread()\n    }\n}\n\nimport XCTest\n\nextension XCTestCase {\n    func wait(for: [XCTestExpectation], timeout: TimeInterval, file: StaticString = #file, line: UInt = #line) {\n    #if !(swift(>=4.0) && !swift(>=4.1))\n        let line = Int(line)\n    #endif\n        waitForExpectations(timeout: timeout, file: file, line: line)\n    }\n}\n\nextension XCTestExpectation {\n    func fulfill() {\n        fulfill(#file, line: #line)\n    }\n}\n#endif\n"
  },
  {
    "path": "Tests/CorePromise/WhenConcurrentTests.swift",
    "content": "import XCTest\nimport PromiseKit\n\nclass WhenConcurrentTestCase_Swift: XCTestCase {\n\n    func testWhen() {\n        let e = expectation(description: \"\")\n\n        var numbers = (0..<42).makeIterator()\n        let squareNumbers = numbers.map { $0 * $0 }\n\n        let generator = AnyIterator<Guarantee<Int>> {\n            guard let number = numbers.next() else {\n                return nil\n            }\n\n            return after(.milliseconds(10)).map {\n                return number * number\n            }\n        }\n\n        when(fulfilled: generator, concurrently: 5).done { numbers in\n            if numbers == squareNumbers {\n                e.fulfill()\n            }\n        }.silenceWarning()\n\n        waitForExpectations(timeout: 3, handler: nil)\n    }\n\n    func testWhenEmptyGenerator() {\n        let e = expectation(description: \"\")\n\n        let generator = AnyIterator<Promise<Int>> {\n            return nil\n        }\n\n        when(fulfilled: generator, concurrently: 5).done { numbers in\n            if numbers.count == 0 {\n                e.fulfill()\n            }\n        }.silenceWarning()\n\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n    func testWhenGeneratorError() {\n        enum LocalError: Error {\n            case Unknown\n            case DivisionByZero\n        }\n\n        let expectedErrorIndex = 42\n        let expectedError = LocalError.DivisionByZero\n\n        let e = expectation(description: \"\")\n\n        var numbers = (-expectedErrorIndex..<expectedErrorIndex).makeIterator()\n\n        let generator = AnyIterator<Promise<Int>> {\n            guard let number = numbers.next() else {\n                return nil\n            }\n\n            return after(.milliseconds(10)).then { _ -> Promise<Int> in\n                if number != 0 {\n                    return Promise(error: expectedError)\n                } else {\n                    return .value(100500 / number)\n                }\n            }\n        }\n\n        when(fulfilled: generator, concurrently: 3)\n            .catch { error in\n                guard let error = error as? LocalError else {\n                    return\n                }\n                guard case .DivisionByZero = error else {\n                    return\n                }\n                e.fulfill()\n            }\n\n        waitForExpectations(timeout: 3, handler: nil)\n    }\n\n    func testWhenConcurrency() {\n        let expectedConcurrently = 4\n        var currentConcurrently = 0\n        var maxConcurrently = 0\n\n        let e = expectation(description: \"\")\n\n        var numbers = (0..<42).makeIterator()\n\n        let generator = AnyIterator<Promise<Int>> {\n            currentConcurrently += 1\n            maxConcurrently = max(maxConcurrently, currentConcurrently)\n\n            guard let number = numbers.next() else {\n                return nil\n            }\n\n            return after(.milliseconds(10)).then(on: .main) { _ -> Promise<Int> in\n                currentConcurrently -= 1\n                return .value(number * number)\n            }\n        }\n\n        when(fulfilled: generator, concurrently: expectedConcurrently).done { _ in\n            XCTAssertEqual(expectedConcurrently, maxConcurrently)\n            e.fulfill()\n        }.silenceWarning()\n\n        waitForExpectations(timeout: 3)\n    }\n\n    func testWhenConcurrencyLessThanZero() {\n        let generator = AnyIterator<Promise<Int>> { XCTFail(); return nil }\n\n        let p1 = when(fulfilled: generator, concurrently: 0)\n        let p2 = when(fulfilled: generator, concurrently: -1)\n\n        guard let e1 = p1.error else { return XCTFail() }\n        guard let e2 = p2.error else { return XCTFail() }\n        guard case PMKError.badInput = e1 else { return XCTFail() }\n        guard case PMKError.badInput = e2 else { return XCTFail() }\n    }\n\n    func testStopsDequeueingOnceRejected() {\n        let ex = expectation(description: \"\")\n        enum Error: Swift.Error { case dummy }\n\n        var x: UInt = 0\n        let generator = AnyIterator<Promise<Void>> {\n            x += 1\n            switch x {\n            case 0:\n                fatalError()\n            case 1:\n                return Promise()\n            case 2:\n                return Promise(error: Error.dummy)\n            case _:\n                XCTFail()\n                return nil\n            }\n        }\n\n        when(fulfilled: generator, concurrently: 1).done {\n            XCTFail(\"\\($0)\")\n        }.catch { error in\n            ex.fulfill()\n        }\n\n        waitForExpectations(timeout: 3)\n    }\n\n    func testWhenResolvedContinuesWhenRejected() {\n    #if swift(>=5.3)\n        let ex = expectation(description: \"\")\n        enum Error: Swift.Error { case dummy }\n\n        var x: UInt = 0\n        let generator = AnyIterator<Promise<Void>> {\n            x += 1\n            switch x {\n            case 0:\n                fatalError()\n            case 1:\n                return Promise()\n            case 2:\n                return Promise(error: Error.dummy)\n            case 3:\n                return Promise()\n            case _:\n                return nil\n            }\n        }\n\n        when(resolved: generator, concurrently: 1).done { results in\n            XCTAssertEqual(results.count, 3)\n            ex.fulfill()\n        }\n\n        waitForExpectations(timeout: 3)\n    #endif\n    }\n}\n"
  },
  {
    "path": "Tests/CorePromise/WhenResolvedTests.swift",
    "content": "//  Created by Austin Feight on 3/19/16.\n//  Copyright © 2016 Max Howell. All rights reserved.\n\nimport PromiseKit\nimport XCTest\n\nclass JoinTests: XCTestCase {\n    func testImmediates() {\n        let successPromise = Promise()\n\n        var joinFinished = false\n        when(resolved: successPromise).done(on: nil) { _ in joinFinished = true }\n        XCTAssert(joinFinished, \"Join immediately finishes on fulfilled promise\")\n        \n        let promise2 = Promise.value(2)\n        let promise3 = Promise.value(3)\n        let promise4 = Promise.value(4)\n        var join2Finished = false\n        when(resolved: promise2, promise3, promise4).done(on: nil) { _ in join2Finished = true }\n        XCTAssert(join2Finished, \"Join immediately finishes on fulfilled promises\")\n    }\n\n    func testFulfilledAfterAllResolve() {\n        let (promise1, seal1) = Promise<Void>.pending()\n        let (promise2, seal2) = Promise<Void>.pending()\n        let (promise3, seal3) = Promise<Void>.pending()\n        \n        var finished = false\n        when(resolved: promise1, promise2, promise3).done(on: nil) { _ in finished = true }\n        XCTAssertFalse(finished, \"Not all promises have resolved\")\n        \n        seal1.fulfill_()\n        XCTAssertFalse(finished, \"Not all promises have resolved\")\n        \n        seal2.fulfill_()\n        XCTAssertFalse(finished, \"Not all promises have resolved\")\n        \n        seal3.fulfill_()\n        XCTAssert(finished, \"All promises have resolved\")\n    }\n}\n"
  },
  {
    "path": "Tests/CorePromise/WhenTests.swift",
    "content": "import PromiseKit\nimport Dispatch\nimport XCTest\n\nclass WhenTests: XCTestCase {\n\n    func testEmpty() {\n        let e1 = expectation(description: \"\")\n        let promises: [Promise<Void>] = []\n        when(fulfilled: promises).done { _ in\n            e1.fulfill()\n        }.silenceWarning()\n\n        let e2 = expectation(description: \"\")\n        when(resolved: promises).done { _ in\n            e2.fulfill()\n        }.silenceWarning()\n\n        wait(for: [e1, e2], timeout: 1)\n    }\n\n    func testInt() {\n        let e1 = expectation(description: \"\")\n        let p1 = Promise.value(1)\n        let p2 = Promise.value(2)\n        let p3 = Promise.value(3)\n        let p4 = Promise.value(4)\n\n        when(fulfilled: [p1, p2, p3, p4]).done { x in\n            XCTAssertEqual(x[0], 1)\n            XCTAssertEqual(x[1], 2)\n            XCTAssertEqual(x[2], 3)\n            XCTAssertEqual(x[3], 4)\n            XCTAssertEqual(x.count, 4)\n            e1.fulfill()\n        }.silenceWarning()\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n    func testAnyInt() {\n        #if swift(>=5.7)\n        let e1 = expectation(description: \"\")\n        let p1 = Promise.value(1)\n        let g2 = Guarantee.value(2)\n        let p3 = Promise.value(3)\n        let g4 = Guarantee.value(4)\n\n        when(fulfilled: [p1, g2, p3, g4]).done { x in\n            XCTAssertEqual(x[0] as? Int, 1)\n            XCTAssertEqual(x[1] as? Int, 2)\n            XCTAssertEqual(x[2] as? Int, 3)\n            XCTAssertEqual(x[3] as? Int, 4)\n            XCTAssertEqual(x.count, 4)\n            e1.fulfill()\n        }.silenceWarning()\n        waitForExpectations(timeout: 1, handler: nil)\n        #endif\n    }\n    \n    func testParameterPacks() {\n        #if swift(>=5.9)\n        let e1 = expectation(description: \"\")\n        let p1 = Promise.value(1)\n        let g2 = Guarantee.value(\"Hello\")\n        let p3 = Promise.value(\"world\")\n        let g4 = Guarantee.value(2)\n\n        when(fulfilled: p1, g2, p3, g4).done { x1, x2, x3, x4 in\n            XCTAssertEqual(x1, 1)\n            XCTAssertEqual(x2, \"Hello\")\n            XCTAssertEqual(x3, \"world\")\n            XCTAssertEqual(x4, 2)\n            e1.fulfill()\n        }.silenceWarning()\n        waitForExpectations(timeout: 1, handler: nil)\n        #endif\n    }\n    \n    func testDoubleTuple() {\n        let e1 = expectation(description: \"\")\n        let p1 = Promise.value(1)\n        let p2 = Promise.value(\"abc\")\n        when(fulfilled: p1, p2).done{ x, y in\n            XCTAssertEqual(x, 1)\n            XCTAssertEqual(y, \"abc\")\n            e1.fulfill()\n        }.silenceWarning()\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n    func testTripleTuple() {\n        let e1 = expectation(description: \"\")\n        let p1 = Promise.value(1)\n        let p2 = Promise.value(\"abc\")\n        let p3 = Promise.value(     1.0)\n        when(fulfilled: p1, p2, p3).done { u, v, w in\n            XCTAssertEqual(1, u)\n            XCTAssertEqual(\"abc\", v)\n            XCTAssertEqual(1.0, w)\n            e1.fulfill()\n        }.silenceWarning()\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n    func testQuadrupleTuple() {\n        let e1 = expectation(description: \"\")\n        let p1 = Promise.value(1)\n        let p2 = Promise.value(\"abc\")\n        let p3 = Promise.value(1.0)\n        let p4 = Promise.value(true)\n        when(fulfilled: p1, p2, p3, p4).done { u, v, w, x in\n            XCTAssertEqual(1, u)\n            XCTAssertEqual(\"abc\", v)\n            XCTAssertEqual(1.0, w)\n            XCTAssertEqual(true, x)\n            e1.fulfill()\n        }.silenceWarning()\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n    func testQuintupleTuple() {\n        let e1 = expectation(description: \"\")\n        let p1 = Promise.value(1)\n        let p2 = Promise.value(\"abc\")\n        let p3 = Promise.value(1.0)\n        let p4 = Promise.value(true)\n        let p5 = Promise.value(\"a\" as Character)\n        when(fulfilled: p1, p2, p3, p4, p5).done { u, v, w, x, y in\n            XCTAssertEqual(1, u)\n            XCTAssertEqual(\"abc\", v)\n            XCTAssertEqual(1.0, w)\n            XCTAssertEqual(true, x)\n            XCTAssertEqual(\"a\" as Character, y)\n            e1.fulfill()\n        }.silenceWarning()\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n    func testVoid() {\n        let e1 = expectation(description: \"\")\n        let p1 = Promise.value(1).done { _ in }\n        let p2 = Promise.value(2).done { _ in }\n        let p3 = Promise.value(3).done { _ in }\n        let p4 = Promise.value(4).done { _ in }\n\n        when(fulfilled: p1, p2, p3, p4).done(e1.fulfill).silenceWarning()\n\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n    \n    func testRejected() {\n        enum Error: Swift.Error { case dummy }\n\n        let e1 = expectation(description: \"\")\n        let p1 = after(.milliseconds(100)).map{ true }\n        let p2: Promise<Bool> = after(.milliseconds(200)).map{ throw Error.dummy }\n        let p3 = Promise.value(false)\n            \n        when(fulfilled: p1, p2, p3).catch { _ in\n            e1.fulfill()\n        }\n        \n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n    func testProgress() {\n        let ex = expectation(description: \"\")\n\n        XCTAssertNil(Progress.current())\n\n        let p1 = after(.milliseconds(10))\n        let p2 = after(.milliseconds(20))\n        let p3 = after(.milliseconds(30))\n        let p4 = after(.milliseconds(40))\n\n        let progress = Progress(totalUnitCount: 1)\n        progress.becomeCurrent(withPendingUnitCount: 1)\n\n        when(guarantees: p1, p2, p3, p4).done { _ in\n            XCTAssertEqual(progress.completedUnitCount, 1)\n            ex.fulfill()\n        }\n\n        progress.resignCurrent()\n        \n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n    func testProgressDoesNotExceed100Percent() {\n        let ex1 = expectation(description: \"\")\n        let ex2 = expectation(description: \"\")\n\n        XCTAssertNil(Progress.current())\n\n        let p1 = after(.milliseconds(10))\n        let p2 = after(.milliseconds(20)).done { throw NSError(domain: \"a\", code: 1, userInfo: nil) }\n        let p3 = after(.milliseconds(30))\n        let p4 = after(.milliseconds(40))\n\n        let progress = Progress(totalUnitCount: 1)\n        progress.becomeCurrent(withPendingUnitCount: 1)\n\n        let promise = when(fulfilled: p1, p2, p3, p4)\n\n        progress.resignCurrent()\n\n        promise.catch { _ in\n            ex2.fulfill()\n        }\n\n        var x = 0\n        func finally() {\n            x += 1\n            if x == 4 {\n                XCTAssertLessThanOrEqual(1, progress.fractionCompleted)\n                XCTAssertEqual(progress.completedUnitCount, 1)\n                ex1.fulfill()\n            }\n        }\n\n        let q = DispatchQueue.main\n        p1.done(on: q, finally)\n        p2.ensure(on: q, finally).silenceWarning()\n        p3.done(on: q, finally)\n        p4.done(on: q, finally)\n\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n    func testUnhandledErrorHandlerDoesNotFire() {\n        enum Error: Swift.Error {\n            case test\n        }\n\n        let ex = expectation(description: \"\")\n        let p1 = Promise<Void>(error: Error.test)\n        let p2 = after(.milliseconds(100))\n        when(fulfilled: p1, p2).done{ _ in XCTFail() }.catch { error in\n            XCTAssertTrue(error as? Error == Error.test)\n            ex.fulfill()\n        }\n\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n    func testUnhandledErrorHandlerDoesNotFireForStragglers() {\n        enum Error: Swift.Error {\n            case test\n            case straggler\n        }\n\n        let ex1 = expectation(description: \"\")\n        let ex2 = expectation(description: \"\")\n        let ex3 = expectation(description: \"\")\n\n        let p1 = Promise<Void>(error: Error.test)\n        let p2 = after(.milliseconds(100)).done { throw Error.straggler }\n        let p3 = after(.milliseconds(200)).done { throw Error.straggler }\n\n        let whenFulfilledP1P2P3: Promise<(Void, Void, Void)> = when(fulfilled: p1, p2, p3)\n        whenFulfilledP1P2P3.catch { error -> Void in\n            XCTAssertTrue(Error.test == error as? Error)\n            ex1.fulfill()\n        }\n\n        p2.ensure { after(.milliseconds(100)).done(ex2.fulfill) }.silenceWarning()\n        p3.ensure { after(.milliseconds(100)).done(ex3.fulfill) }.silenceWarning()\n\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n\n    func testAllSealedRejectedFirstOneRejects() {\n        enum Error: Swift.Error {\n            case test1\n            case test2\n            case test3\n        }\n\n        let ex = expectation(description: \"\")\n        let p1 = Promise<Void>(error: Error.test1)\n        let p2 = Promise<Void>(error: Error.test2)\n        let p3 = Promise<Void>(error: Error.test3)\n\n        let whenFulfilledP1P2P3: Promise<Void> = when(fulfilled: p1, p2, p3)\n        whenFulfilledP1P2P3.catch { error in\n            XCTAssertTrue(error as? Error == Error.test1)\n            ex.fulfill()\n        }\n\n        waitForExpectations(timeout: 1)\n    }\n\n    func testGuaranteesWhenVoidVarArgs() {\n        let ex1 = expectation(description: \"\")\n        var someNumber = 0\n        let g1 = Guarantee<Void> { resolver in\n            someNumber += 1\n            resolver(())\n        }\n        let g2 = Guarantee<Void> { resolver in\n            someNumber += 2\n            resolver(())\n        }\n        when(g1, g2).done {\n            XCTAssertEqual(someNumber, 3)\n            ex1.fulfill()\n        }\n        wait(for: [ex1], timeout: 10)\n    }\n    \n    func testGuaranteesWhenVarArgs() {\n        let ex1 = expectation(description: \"\")\n        let g1 = Guarantee<Int>.value(1)\n        let g2 = Guarantee<Int>.value(4)\n        let g3 = Guarantee<Int>.value(2)\n        let g4 = Guarantee<Int>.value(5)\n        let g5 = Guarantee<Int>.value(3)\n        when(g1, g2, g3, g4, g5).done {\n            XCTAssertEqual($0, [1, 4, 2, 5, 3])\n            ex1.fulfill()\n        }\n        wait(for: [ex1], timeout: 10)\n    }\n    \n    func testGuaranteesWhenVoidArray() {\n        let ex1 = expectation(description: \"\")\n        var someNumber = 0\n        when(guarantees: (0..<100).map { _ in\n            Guarantee<Void> { resolver in\n                someNumber += 1\n                resolver(())\n            }\n        }).done {\n            XCTAssertEqual(someNumber, 100)\n            ex1.fulfill()\n        }\n\n        wait(for: [ex1], timeout: 10)\n    }\n    \n    func testGuaranteesWhenArray() {\n        let ex1 = expectation(description: \"\")\n        when(guarantees: (0..<100).map {\n            Guarantee<Int>.value($0)\n        }).done {\n            XCTAssertEqual($0, Array(0..<100))\n            ex1.fulfill()\n        }\n\n        wait(for: [ex1], timeout: 10)\n    }\n    \n    func testDoubleTupleGuarantees() {\n        let e1 = expectation(description: \"\")\n        let g1 = Guarantee.value(1)\n        let g2 = Guarantee.value(\"abc\")\n        when(guarantees: g1, g2).done { x, y in\n            XCTAssertEqual(x, 1)\n            XCTAssertEqual(y, \"abc\")\n            e1.fulfill()\n        }\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n    \n    func testTripleTupleGuarantees() {\n        let e1 = expectation(description: \"\")\n        let g1 = Guarantee.value(1)\n        let g2 = Guarantee.value(\"abc\")\n        let g3 = Guarantee.value(     1.0)\n        when(guarantees: g1, g2, g3).done { u, v, w in\n            XCTAssertEqual(1, u)\n            XCTAssertEqual(\"abc\", v)\n            XCTAssertEqual(1.0, w)\n            e1.fulfill()\n        }\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n    \n    func testQuadrupleTupleGuarantees() {\n        let e1 = expectation(description: \"\")\n        let g1 = Guarantee.value(1)\n        let g2 = Guarantee.value(\"abc\")\n        let g3 = Guarantee.value(1.0)\n        let g4 = Guarantee.value(true)\n        when(guarantees: g1, g2, g3, g4).done { u, v, w, x in\n            XCTAssertEqual(1, u)\n            XCTAssertEqual(\"abc\", v)\n            XCTAssertEqual(1.0, w)\n            XCTAssertEqual(true, x)\n            e1.fulfill()\n        }\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n    \n    func testQuintupleTupleGuarantees() {\n        let e1 = expectation(description: \"\")\n        let g1 = Guarantee.value(1)\n        let g2 = Guarantee.value(\"abc\")\n        let g3 = Guarantee.value(1.0)\n        let g4 = Guarantee.value(true)\n        let g5 = Guarantee.value(\"a\" as Character)\n        when(guarantees: g1, g2, g3, g4, g5).done { u, v, w, x, y in\n            XCTAssertEqual(1, u)\n            XCTAssertEqual(\"abc\", v)\n            XCTAssertEqual(1.0, w)\n            XCTAssertEqual(true, x)\n            XCTAssertEqual(\"a\" as Character, y)\n            e1.fulfill()\n        }\n        waitForExpectations(timeout: 1, handler: nil)\n    }\n}\n"
  },
  {
    "path": "Tests/CorePromise/XCTestManifests.swift",
    "content": "#if !canImport(ObjectiveC)\nimport XCTest\n\nextension AfterTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__AfterTests = [\n        (\"testNegative\", testNegative),\n        (\"testPositive\", testPositive),\n        (\"testZero\", testZero),\n    ]\n}\n\nextension AsyncTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__AsyncTests = [\n        (\"testAsyncGuaranteeValue\", testAsyncGuaranteeValue),\n        (\"testAsyncGuaranteeValue\", testAsyncGuaranteeValue),\n        (\"testAsyncPromiseCancel\", testAsyncPromiseCancel),\n        (\"testAsyncPromiseCancel\", testAsyncPromiseCancel),\n        (\"testAsyncPromiseThrow\", testAsyncPromiseThrow),\n        (\"testAsyncPromiseThrow\", testAsyncPromiseThrow),\n        (\"testAsyncPromiseValue\", testAsyncPromiseValue),\n        (\"testAsyncPromiseValue\", testAsyncPromiseValue),\n    ]\n}\n\nextension CancellationTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__CancellationTests = [\n        (\"testBridgeToNSError\", testBridgeToNSError),\n        (\"testCancellation\", testCancellation),\n        (\"testDoesntCrashSwift\", testDoesntCrashSwift),\n        (\"testFoundationBridging1\", testFoundationBridging1),\n        (\"testFoundationBridging2\", testFoundationBridging2),\n        (\"testIsCancelled\", testIsCancelled),\n        (\"testRecoverWithCancellation\", testRecoverWithCancellation),\n        (\"testThrowCancellableErrorThatIsNotCancelled\", testThrowCancellableErrorThatIsNotCancelled),\n    ]\n}\n\nextension CatchableTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__CatchableTests = [\n        (\"test__conditional_recover\", test__conditional_recover),\n        (\"test__conditional_recover__fulfilled_path\", test__conditional_recover__fulfilled_path),\n        (\"test__conditional_recover__ignores_cancellation_but_fed_cancellation\", test__conditional_recover__ignores_cancellation_but_fed_cancellation),\n        (\"test__conditional_recover__no_recover\", test__conditional_recover__no_recover),\n        (\"test__full_recover\", test__full_recover),\n        (\"test__full_recover__fulfilled_path\", test__full_recover__fulfilled_path),\n        (\"test__void_specialized_conditional_recover\", test__void_specialized_conditional_recover),\n        (\"test__void_specialized_conditional_recover__fulfilled_path\", test__void_specialized_conditional_recover__fulfilled_path),\n        (\"test__void_specialized_conditional_recover__ignores_cancellation_but_fed_cancellation\", test__void_specialized_conditional_recover__ignores_cancellation_but_fed_cancellation),\n        (\"test__void_specialized_conditional_recover__no_recover\", test__void_specialized_conditional_recover__no_recover),\n        (\"test__void_specialized_full_recover\", test__void_specialized_full_recover),\n        (\"test__void_specialized_full_recover__fulfilled_path\", test__void_specialized_full_recover__fulfilled_path),\n        (\"testCauterize\", testCauterize),\n        (\"testEnsureThen_Error\", testEnsureThen_Error),\n        (\"testEnsureThen_Value\", testEnsureThen_Value),\n        (\"testFinally\", testFinally),\n    ]\n}\n\nextension CombineTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__CombineTests = [\n        (\"testCombineGuaranteeValue\", testCombineGuaranteeValue),\n        (\"testCombinePromiseThrow\", testCombinePromiseThrow),\n        (\"testCombinePromiseValue\", testCombinePromiseValue),\n        (\"testGuaranteeCombineValue\", testGuaranteeCombineValue),\n        (\"testPromiseCombineThrows\", testPromiseCombineThrows),\n        (\"testPromiseCombineValue\", testPromiseCombineValue),\n    ]\n}\n\nextension GuaranteeTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__GuaranteeTests = [\n        (\"testCompactMapValues\", testCompactMapValues),\n        (\"testCompactMapValuesByKeyPath\", testCompactMapValuesByKeyPath),\n        (\"testFilterValues\", testFilterValues),\n        (\"testFilterValuesByKeyPath\", testFilterValuesByKeyPath),\n        (\"testFlatMapValues\", testFlatMapValues),\n        (\"testInit\", testInit),\n        (\"testMap\", testMap),\n        (\"testMapByKeyPath\", testMapByKeyPath),\n        (\"testMapValues\", testMapValues),\n        (\"testMapValuesByKeyPath\", testMapValuesByKeyPath),\n        (\"testNoAmbiguityForValue\", testNoAmbiguityForValue),\n        (\"testSorted\", testSorted),\n        (\"testSortedBy\", testSortedBy),\n        (\"testThenFlatMap\", testThenFlatMap),\n        (\"testThenMap\", testThenMap),\n        (\"testWait\", testWait),\n    ]\n}\n\nextension HangTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__HangTests = [\n        (\"test\", test),\n        (\"testError\", testError),\n    ]\n}\n\nextension JoinTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__JoinTests = [\n        (\"testFulfilledAfterAllResolve\", testFulfilledAfterAllResolve),\n        (\"testImmediates\", testImmediates),\n    ]\n}\n\nextension LoggingTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__LoggingTests = [\n        (\"testCauterizeIsLogged\", testCauterizeIsLogged),\n        (\"testGuaranteeWaitOnMainThreadLogged\", testGuaranteeWaitOnMainThreadLogged),\n        (\"testLogging\", testLogging),\n        (\"testPendingGuaranteeDeallocatedIsLogged\", testPendingGuaranteeDeallocatedIsLogged),\n        (\"testPendingPromiseDeallocatedIsLogged\", testPendingPromiseDeallocatedIsLogged),\n        (\"testPromiseWaitOnMainThreadLogged\", testPromiseWaitOnMainThreadLogged),\n    ]\n}\n\nextension PMKDefaultDispatchQueueTest {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__PMKDefaultDispatchQueueTest = [\n        (\"testOverrodeDefaultAlwaysQueue\", testOverrodeDefaultAlwaysQueue),\n        (\"testOverrodeDefaultCatchQueue\", testOverrodeDefaultCatchQueue),\n        (\"testOverrodeDefaultThenQueue\", testOverrodeDefaultThenQueue),\n    ]\n}\n\nextension PMKErrorTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__PMKErrorTests = [\n        (\"testCustomDebugStringConvertible\", testCustomDebugStringConvertible),\n        (\"testCustomStringConvertible\", testCustomStringConvertible),\n    ]\n}\n\nextension PromiseTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__PromiseTests = [\n        (\"testCanMakeVoidPromise\", testCanMakeVoidPromise),\n        (\"testCannotFulfillWithError\", testCannotFulfillWithError),\n        (\"testCustomStringConvertible\", testCustomStringConvertible),\n        (\"testDispatchQueueAsyncExtensionCanThrowInBody\", testDispatchQueueAsyncExtensionCanThrowInBody),\n        (\"testDispatchQueueAsyncExtensionReturnsPromise\", testDispatchQueueAsyncExtensionReturnsPromise),\n        (\"testIsFulfilled\", testIsFulfilled),\n        (\"testIsPending\", testIsPending),\n        (\"testIsRejected\", testIsRejected),\n        (\"testIsResolved\", testIsResolved),\n        (\"testNoAmbiguityForValue\", testNoAmbiguityForValue),\n        (\"testPipeForResolved\", testPipeForResolved),\n        (\"testThrowInFirstly\", testThrowInFirstly),\n        (\"testThrowInInitializer\", testThrowInInitializer),\n        (\"testWait\", testWait),\n    ]\n}\n\nextension RaceTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__RaceTests = [\n        (\"test1\", test1),\n        (\"test1Array\", test1Array),\n        (\"test2\", test2),\n        (\"test2Array\", test2Array),\n        (\"testEmptyArray\", testEmptyArray),\n        (\"testFulfilled\", testFulfilled),\n        (\"testFulfilledEmptyArray\", testFulfilledEmptyArray),\n        (\"testFulfilledWithNoWinner\", testFulfilledWithNoWinner),\n    ]\n}\n\nextension RegressionTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__RegressionTests = [\n        (\"testReturningPreviousPromiseWorks\", testReturningPreviousPromiseWorks),\n    ]\n}\n\nextension StressTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__StressTests = [\n        (\"testThenDataRace\", testThenDataRace),\n        (\"testThensAreSequentialForLongTime\", testThensAreSequentialForLongTime),\n        (\"testZalgoDataRace\", testZalgoDataRace),\n    ]\n}\n\nextension ThenableTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__ThenableTests = [\n        (\"testBarrier\", testBarrier),\n        (\"testCompactMap\", testCompactMap),\n        (\"testCompactMapByKeyPath\", testCompactMapByKeyPath),\n        (\"testCompactMapThrows\", testCompactMapThrows),\n        (\"testCompactMapValues\", testCompactMapValues),\n        (\"testCompactMapValuesByKeyPath\", testCompactMapValuesByKeyPath),\n        (\"testDispatchFlagsSyntax\", testDispatchFlagsSyntax),\n        (\"testFilterValues\", testFilterValues),\n        (\"testFilterValuesByKeyPath\", testFilterValuesByKeyPath),\n        (\"testFirstValueForEmpty\", testFirstValueForEmpty),\n        (\"testGet\", testGet),\n        (\"testLastValueForEmpty\", testLastValueForEmpty),\n        (\"testMap\", testMap),\n        (\"testMapByKeyPath\", testMapByKeyPath),\n        (\"testMapValues\", testMapValues),\n        (\"testMapValuesByKeyPath\", testMapValuesByKeyPath),\n        (\"testPMKErrorCompactMap\", testPMKErrorCompactMap),\n        (\"testRejectedPromiseCompactMap\", testRejectedPromiseCompactMap),\n        (\"testThenFlatMap\", testThenFlatMap),\n        (\"testThenMap\", testThenMap),\n        (\"testThenOffRejected\", testThenOffRejected),\n    ]\n}\n\nextension WhenConcurrentTestCase_Swift {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__WhenConcurrentTestCase_Swift = [\n        (\"testStopsDequeueingOnceRejected\", testStopsDequeueingOnceRejected),\n        (\"testWhen\", testWhen),\n        (\"testWhenConcurrency\", testWhenConcurrency),\n        (\"testWhenConcurrencyLessThanZero\", testWhenConcurrencyLessThanZero),\n        (\"testWhenEmptyGenerator\", testWhenEmptyGenerator),\n        (\"testWhenGeneratorError\", testWhenGeneratorError),\n        (\"testWhenResolvedContinuesWhenRejected\", testWhenResolvedContinuesWhenRejected),\n    ]\n}\n\nextension WhenTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__WhenTests = [\n        (\"testAllSealedRejectedFirstOneRejects\", testAllSealedRejectedFirstOneRejects),\n        (\"testAnyInt\", testAnyInt),\n        (\"testDoubleTuple\", testDoubleTuple),\n        (\"testDoubleTupleGuarantees\", testDoubleTupleGuarantees),\n        (\"testEmpty\", testEmpty),\n        (\"testGuaranteesWhenArray\", testGuaranteesWhenArray),\n        (\"testGuaranteesWhenVarArgs\", testGuaranteesWhenVarArgs),\n        (\"testGuaranteesWhenVoidArray\", testGuaranteesWhenVoidArray),\n        (\"testGuaranteesWhenVoidVarArgs\", testGuaranteesWhenVoidVarArgs),\n        (\"testInt\", testInt),\n        (\"testProgress\", testProgress),\n        (\"testProgressDoesNotExceed100Percent\", testProgressDoesNotExceed100Percent),\n        (\"testQuadrupleTuple\", testQuadrupleTuple),\n        (\"testQuadrupleTupleGuarantees\", testQuadrupleTupleGuarantees),\n        (\"testQuintupleTuple\", testQuintupleTuple),\n        (\"testQuintupleTupleGuarantees\", testQuintupleTupleGuarantees),\n        (\"testRejected\", testRejected),\n        (\"testTripleTuple\", testTripleTuple),\n        (\"testTripleTupleGuarantees\", testTripleTupleGuarantees),\n        (\"testUnhandledErrorHandlerDoesNotFire\", testUnhandledErrorHandlerDoesNotFire),\n        (\"testUnhandledErrorHandlerDoesNotFireForStragglers\", testUnhandledErrorHandlerDoesNotFireForStragglers),\n        (\"testVoid\", testVoid),\n    ]\n}\n\nextension WrapTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__WrapTests = [\n        (\"testError\", testError),\n        (\"testInvalidCallingConvention\", testInvalidCallingConvention),\n        (\"testInvertedCallingConvention\", testInvertedCallingConvention),\n        (\"testIsFulfilled\", testIsFulfilled),\n        (\"testNonOptionalFirstParameter\", testNonOptionalFirstParameter),\n        (\"testPendingPromiseDeallocated\", testPendingPromiseDeallocated),\n        (\"testSuccess\", testSuccess),\n        (\"testSwiftResultError\", testSwiftResultError),\n        (\"testSwiftResultSuccess\", testSwiftResultSuccess),\n        (\"testVoidCompletionValue\", testVoidCompletionValue),\n        (\"testVoidResolverFulfillAmbiguity\", testVoidResolverFulfillAmbiguity),\n    ]\n}\n\nextension ZalgoTests {\n    // DO NOT MODIFY: This is autogenerated, use:\n    //   `swift test --generate-linuxmain`\n    // to regenerate.\n    static let __allTests__ZalgoTests = [\n        (\"test1\", test1),\n        (\"test2\", test2),\n        (\"test3\", test3),\n        (\"test4\", test4),\n    ]\n}\n\npublic func __allTests() -> [XCTestCaseEntry] {\n    return [\n        testCase(AfterTests.__allTests__AfterTests),\n        testCase(AsyncTests.__allTests__AsyncTests),\n        testCase(CancellationTests.__allTests__CancellationTests),\n        testCase(CatchableTests.__allTests__CatchableTests),\n        testCase(CombineTests.__allTests__CombineTests),\n        testCase(GuaranteeTests.__allTests__GuaranteeTests),\n        testCase(HangTests.__allTests__HangTests),\n        testCase(JoinTests.__allTests__JoinTests),\n        testCase(LoggingTests.__allTests__LoggingTests),\n        testCase(PMKDefaultDispatchQueueTest.__allTests__PMKDefaultDispatchQueueTest),\n        testCase(PMKErrorTests.__allTests__PMKErrorTests),\n        testCase(PromiseTests.__allTests__PromiseTests),\n        testCase(RaceTests.__allTests__RaceTests),\n        testCase(RegressionTests.__allTests__RegressionTests),\n        testCase(StressTests.__allTests__StressTests),\n        testCase(ThenableTests.__allTests__ThenableTests),\n        testCase(WhenConcurrentTestCase_Swift.__allTests__WhenConcurrentTestCase_Swift),\n        testCase(WhenTests.__allTests__WhenTests),\n        testCase(WrapTests.__allTests__WrapTests),\n        testCase(ZalgoTests.__allTests__ZalgoTests),\n    ]\n}\n#endif\n"
  },
  {
    "path": "Tests/CorePromise/ZalgoTests.swift",
    "content": "import XCTest\nimport PromiseKit\n\nclass ZalgoTests: XCTestCase {\n    func test1() {\n        var resolved = false\n        Promise.value(1).done(on: nil) { _ in\n            resolved = true\n        }.silenceWarning()\n        XCTAssertTrue(resolved)\n    }\n\n    func test2() {\n        let p1 = Promise.value(1).map(on: nil) { x in\n            return 2\n        }\n        XCTAssertEqual(p1.value!, 2)\n        \n        var x = 0\n        \n        let (p2, seal) = Promise<Int>.pending()\n        p2.done(on: nil) { _ in\n            x = 1\n        }.silenceWarning()\n        XCTAssertEqual(x, 0)\n        \n        seal.fulfill(1)\n        XCTAssertEqual(x, 1)\n    }\n\n    // returning a pending promise from its own zalgo’d then handler doesn’t hang\n    func test3() {\n        let ex = (expectation(description: \"\"), expectation(description: \"\"))\n\n        var p1: Promise<Void>!\n        p1 = after(.milliseconds(100)).then(on: nil) { _ -> Promise<Void> in\n            ex.0.fulfill()\n            return p1\n        }\n\n        p1.catch { err in\n            defer{ ex.1.fulfill() }\n            guard case PMKError.returnedSelf = err else { return XCTFail() }\n        }\n\n        waitForExpectations(timeout: 1)\n    }\n\n    // return a sealed promise from its own zalgo’d then handler doesn’t hang\n    func test4() {\n        let ex = expectation(description: \"\")\n        let p1 = Promise.value(1)\n        p1.then(on: nil) { _ -> Promise<Int> in\n            ex.fulfill()\n            return p1\n        }.silenceWarning()\n        waitForExpectations(timeout: 1)\n    }\n}\n"
  },
  {
    "path": "Tests/DeprecationTests.swift",
    "content": "import PromiseKit\nimport XCTest\n\nclass DeprecationTests: XCTestCase {\n    func testWrap1() {\n        let dummy = 10\n\n        func completion(_ body: (_ a: Int?, _ b: Error?) -> Void) {\n            body(dummy, nil)\n        }\n\n        let ex = expectation(description: \"\")\n        wrap(completion).done {\n            XCTAssertEqual($0, dummy)\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testWrap2() {\n        let dummy = 10\n\n        func completion(_ body: (_ a: Int, _ b: Error?) -> Void) {\n            body(dummy, nil)\n        }\n\n        let ex = expectation(description: \"\")\n        wrap(completion).done {\n            XCTAssertEqual($0, dummy)\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testWrap3() {\n        let dummy = 10\n\n        func completion(_ body: (_ a: Error?, _ b: Int?) -> Void) {\n            body(nil, dummy)\n        }\n\n        let ex = expectation(description: \"\")\n        wrap(completion).done {\n            XCTAssertEqual($0, dummy)\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testWrap4() {\n        let dummy = 10\n\n        func completion(_ body: (_ a: Error?) -> Void) {\n            body(nil)\n        }\n\n        let ex = expectation(description: \"\")\n        wrap(completion).done {\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testWrap5() {\n        let dummy = 10\n\n        func completion(_ body: (_ a: Int) -> Void) {\n            body(dummy)\n        }\n\n        let ex = expectation(description: \"\")\n        wrap(completion).done {\n            XCTAssertEqual($0, dummy)\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testAlways() {\n        let ex = expectation(description: \"\")\n        Promise.value(1).always(execute: ex.fulfill)\n        wait(for: [ex], timeout: 10)\n    }\n\n#if PMKFullDeprecations\n    func testFlatMap() {\n        let ex = expectation(description: \"\")\n        Promise.value(1).flatMap { _ -> Int? in\n            nil\n        }.catch {\n            //TODO should be `flatMap`, but how to enact that without causing\n            // compiler to warn when building PromiseKit for end-users? LOL\n            guard case PMKError.compactMap = $0 else { return XCTFail() }\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testSequenceMap() {\n        let ex = expectation(description: \"\")\n        Promise.value([1, 2]).map {\n            $0 + 1\n        }.done {\n            XCTAssertEqual($0, [2, 3])\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testSequenceFlatMap() {\n        let ex = expectation(description: \"\")\n        Promise.value([1, 2]).flatMap {\n            [$0 + 1, $0 + 2]\n        }.done {\n            XCTAssertEqual($0, [2, 3, 3, 4])\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n#endif\n\n    func testSequenceFilter() {\n        let ex = expectation(description: \"\")\n        Promise.value([0, 1, 2, 3]).filter {\n            $0 < 2\n        }.done {\n            XCTAssertEqual($0, [0, 1])\n            ex.fulfill()\n        }.silenceWarning()\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testSorted() {\n        let ex = expectation(description: \"\")\n        Promise.value([5, 2, 1, 8]).sorted().done {\n            XCTAssertEqual($0, [1,2,5,8])\n            ex.fulfill()\n        }\n        wait(for: [ex], timeout: 10)\n    }\n\n    func testFirst() {\n        XCTAssertEqual(Promise.value([1,2]).first.value, 1)\n    }\n\n    func testLast() {\n        XCTAssertEqual(Promise.value([1,2]).last.value, 2)\n    }\n\n    func testPMKErrorFlatMap() {\n        XCTAssertNotNil(PMKError.flatMap(1, Int.self).errorDescription)\n    }\n}\n\n\nextension Promise {\n    func silenceWarning() {}\n}\n"
  },
  {
    "path": "Tests/JS-A+/.gitignore",
    "content": "# From https://github.com/github/gitignore/blob/master/Node.gitignore\n\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# Typescript v1 declaration files\ntypings/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n\n# next.js build output\n.next\n"
  },
  {
    "path": "Tests/JS-A+/AllTests.swift",
    "content": "//\n//  AllTests.swift\n//  PMKJSA+Tests\n//\n//  Created by Lois Di Qual on 2/28/18.\n//\n\n#if swift(>=3.2) && !os(watchOS)\n\nimport XCTest\nimport PromiseKit\nimport JavaScriptCore\n\nclass AllTests: XCTestCase {\n    \n    func testAll() {\n        \n        let scriptPath = URL(fileURLWithPath: #file).deletingLastPathComponent().appendingPathComponent(\"build/build.js\")\n        guard FileManager.default.fileExists(atPath: scriptPath.path) else {\n            return print(\"Skipping JS-A+: see README for instructions on how to build\")\n        }\n        \n        guard let script = try? String(contentsOf: scriptPath) else {\n            return XCTFail(\"Couldn't read content of test suite JS file\")\n        }\n        \n        let context = JSUtils.sharedContext\n        \n        // Add a global exception handler\n        context.exceptionHandler = { context, exception in\n            guard let exception = exception else {\n                return XCTFail(\"Unknown JS exception\")\n            }\n            JSUtils.printStackTrace(exception: exception, includeExceptionDescription: true)\n        }\n        \n        // Setup mock functions (timers, console.log, etc)\n        let environment = MockNodeEnvironment()\n        environment.setup(with: context)\n        \n        // Expose JSPromise in the javascript context\n        context.setObject(JSPromise.self, forKeyedSubscript: \"JSPromise\" as NSString)\n        \n        // Create adapter\n        guard let adapter = JSValue(object: NSDictionary(), in: context) else {\n            fatalError(\"Couldn't create adapter\")\n        }\n        adapter.setObject(JSAdapter.resolved, forKeyedSubscript: \"resolved\" as NSString)\n        adapter.setObject(JSAdapter.rejected, forKeyedSubscript: \"rejected\" as NSString)\n        adapter.setObject(JSAdapter.deferred, forKeyedSubscript: \"deferred\" as NSString)\n        \n        // Evaluate contents of `build.js`, which exposes `runTests` in the global context\n        context.evaluateScript(script)\n        guard let runTests = context.objectForKeyedSubscript(\"runTests\") else {\n            return XCTFail(\"Couldn't find `runTests` in JS context\")\n        }\n        \n        // Create a callback that's called whenever there's a failure\n        let onFail: @convention(block) (JSValue, JSValue) -> Void = { test, error in\n            guard let test = test.toString(), let error = error.toString() else {\n                return XCTFail(\"Unknown test failure\")\n            }\n            XCTFail(\"\\(test) failed: \\(error)\")\n        }\n        let onFailValue: JSValue = JSValue(object: onFail, in: context)\n        \n        // Create a new callback that we'll send to `runTest` so that it notifies when tests are done running.\n        let expectation = self.expectation(description: \"async\")\n        let onDone: @convention(block) (JSValue) -> Void = { failures in\n            expectation.fulfill()\n        }\n        let onDoneValue: JSValue = JSValue(object: onDone, in: context)\n        \n        // If there's a need to only run one specific test, uncomment the next line and comment the one after\n        // let testName: JSValue = JSValue(object: \"2.3.1\", in: context)\n        let testName = JSUtils.undefined\n        \n        // Call `runTests`\n        runTests.call(withArguments: [adapter, onFailValue, onDoneValue, testName])\n        self.wait(for: [expectation], timeout: 60)\n    }\n}\n\n#endif\n"
  },
  {
    "path": "Tests/JS-A+/JSAdapter.swift",
    "content": "//\n//  JSAdapter.swift\n//  PMKJSA+Tests\n//\n//  Created by Lois Di Qual on 3/2/18.\n//\n\n#if !os(watchOS)\n\nimport Foundation\nimport JavaScriptCore\nimport PromiseKit\n\nenum JSAdapter {\n    \n    static let resolved: @convention(block) (JSValue) -> JSPromise = { value in\n        return JSPromise(promise: .value(value))\n    }\n    \n    static let rejected: @convention(block) (JSValue) -> JSPromise = { reason in\n        let error = JSUtils.JSError(reason: reason)\n        let promise = Promise<JSValue>(error: error)\n        return JSPromise(promise: promise)\n    }\n    \n    static let deferred: @convention(block) () -> JSValue = {\n        \n        let context = JSContext.current()\n        \n        guard let object = JSValue(object: NSDictionary(), in: context) else {\n            fatalError(\"Couldn't create object\")\n        }\n        \n        let pendingPromise = Promise<JSValue>.pending()\n        let jsPromise = JSPromise(promise: pendingPromise.promise)\n        \n        // promise\n        object.setObject(jsPromise, forKeyedSubscript: \"promise\" as NSString)\n        \n        // resolve\n        let resolve: @convention(block) (JSValue) -> Void = { value in\n            pendingPromise.resolver.fulfill(value)\n        }\n        object.setObject(resolve, forKeyedSubscript: \"resolve\" as NSString)\n        \n        // reject\n        let reject: @convention(block) (JSValue) -> Void = { reason in\n            let error = JSUtils.JSError(reason: reason)\n            pendingPromise.resolver.reject(error)\n        }\n        object.setObject(reject, forKeyedSubscript: \"reject\" as NSString)\n        \n        return object\n    }\n}\n\n#endif\n"
  },
  {
    "path": "Tests/JS-A+/JSPromise.swift",
    "content": "//\n//  JSPromise.swift\n//  PMKJSA+Tests\n//\n//  Created by Lois Di Qual on 3/1/18.\n//\n\n#if !os(watchOS)\n\nimport Foundation\nimport XCTest\nimport PromiseKit\nimport JavaScriptCore\n\n@objc protocol JSPromiseProtocol: JSExport {\n    func then(_: JSValue, _: JSValue) -> JSPromise\n}\n\nclass JSPromise: NSObject, JSPromiseProtocol {\n    \n    let promise: Promise<JSValue>\n    \n    init(promise: Promise<JSValue>) {\n        self.promise = promise\n    }\n    \n    func then(_ onFulfilled: JSValue, _ onRejected: JSValue) -> JSPromise {\n        \n        // Keep a reference to the returned promise so we can comply to 2.3.1\n        var returnedPromiseRef: Promise<JSValue>?\n        \n        let afterFulfill = promise.then { value -> Promise<JSValue> in\n            \n            // 2.2.1: ignored if not a function\n            guard JSUtils.isFunction(value: onFulfilled) else {\n                return .value(value)\n            }\n            \n            // Call `onFulfilled`\n            // 2.2.5: onFulfilled/onRejected must be called as functions (with no `this` value)\n            guard let returnValue = try JSUtils.call(function: onFulfilled, arguments: [JSUtils.undefined, value]) else {\n                return .value(value)\n            }\n            \n            // Extract JSPromise.promise if available, or use plain return value\n            if let jsPromise = returnValue.toObjectOf(JSPromise.self) as? JSPromise {\n                \n                // 2.3.1: if returned value is the promise that `then` returned, throw TypeError\n                if jsPromise.promise === returnedPromiseRef {\n                    throw JSUtils.JSError(reason: JSUtils.typeError(message: \"Returned self\"))\n                }\n                return jsPromise.promise\n            } else {\n                return .value(returnValue)\n            }\n        }\n        \n        let afterReject = promise.recover { error -> Promise<JSValue> in\n            \n            // 2.2.1: ignored if not a function\n            guard let jsError = error as? JSUtils.JSError, JSUtils.isFunction(value: onRejected) else {\n                throw error\n            }\n            \n            // Call `onRejected`\n            // 2.2.5: onFulfilled/onRejected must be called as functions (with no `this` value)\n            guard let returnValue = try JSUtils.call(function: onRejected, arguments: [JSUtils.undefined, jsError.reason]) else {\n                throw error\n            }\n            \n            // Extract JSPromise.promise if available, or use plain return value\n            if let jsPromise = returnValue.toObjectOf(JSPromise.self) as? JSPromise {\n                \n                // 2.3.1: if returned value is the promise that `then` returned, throw TypeError\n                if jsPromise.promise === returnedPromiseRef {\n                    throw JSUtils.JSError(reason: JSUtils.typeError(message: \"Returned self\"))\n                }\n                return jsPromise.promise\n            } else {\n                return .value(returnValue)\n            }\n        }\n        \n        let newPromise = Promise<Result<JSValue>> { resolver in\n            _ = promise.tap(resolver.fulfill)\n        }.then(on: nil) { result -> Promise<JSValue> in\n            switch result {\n            case .fulfilled: return afterFulfill\n            case .rejected: return afterReject\n            }\n        }\n        returnedPromiseRef = newPromise\n        \n        return JSPromise(promise: newPromise)\n    }\n}\n\n#endif\n"
  },
  {
    "path": "Tests/JS-A+/JSUtils.swift",
    "content": "//\n//  JSUtils.swift\n//  PMKJSA+Tests\n//\n//  Created by Lois Di Qual on 3/2/18.\n//\n\n#if !os(watchOS)\n\nimport Foundation\nimport JavaScriptCore\n\nenum JSUtils {\n    \n    class JSError: Error {\n        let reason: JSValue\n        init(reason: JSValue) {\n            self.reason = reason\n        }\n    }\n    \n    static let sharedContext: JSContext = {\n        guard let context = JSContext() else {\n            fatalError(\"Couldn't create JS context\")\n        }\n        return context\n    }()\n    \n    static var undefined: JSValue {\n        guard let undefined = JSValue(undefinedIn: JSUtils.sharedContext) else {\n            fatalError(\"Couldn't create `undefined` value\")\n        }\n        return undefined\n    }\n    \n    static func typeError(message: String) -> JSValue {\n        let message = message.replacingOccurrences(of: \"\\\"\", with: \"\\\\\\\"\")\n        let script = \"new TypeError(\\\"\\(message)\\\")\"\n        guard let result = sharedContext.evaluateScript(script) else {\n            fatalError(\"Couldn't create TypeError\")\n        }\n        return result\n    }\n    \n    // @warning: relies on lodash to be present\n    static func isFunction(value: JSValue) -> Bool {\n        guard let context = value.context else {\n            return false\n        }\n        guard let lodash = context.objectForKeyedSubscript(\"_\") else {\n            fatalError(\"Couldn't get lodash in JS context\")\n        }\n        guard let result = lodash.invokeMethod(\"isFunction\", withArguments: [value]) else {\n            fatalError(\"Couldn't invoke _.isFunction\")\n        }\n        return result.toBool()\n    }\n    \n    // Calls a JS function using `Function.prototype.call` and throws any potential exception wrapped in a JSError\n    static func call(function: JSValue, arguments: [JSValue]) throws -> JSValue? {\n        \n        let context = JSUtils.sharedContext\n        \n        // Create a new exception handler that will store a potential exception\n        // thrown in the handler. Save the value of the old handler.\n        var caughtException: JSValue?\n        let savedExceptionHandler = context.exceptionHandler\n        context.exceptionHandler = { context, exception in\n            caughtException = exception\n        }\n        \n        // Call the handler\n        let returnValue = function.invokeMethod(\"call\", withArguments: arguments)\n        context.exceptionHandler = savedExceptionHandler\n        \n        // If an exception was caught, throw it\n        if let exception = caughtException {\n            throw JSError(reason: exception)\n        }\n        \n        return returnValue\n    }\n    \n    static func printCurrentStackTrace() {\n        guard let exception = JSUtils.sharedContext.evaluateScript(\"new Error()\") else {\n            return print(\"Couldn't get current stack trace\")\n        }\n        printStackTrace(exception: exception, includeExceptionDescription: false)\n    }\n    \n    static func printStackTrace(exception: JSValue, includeExceptionDescription: Bool) {\n        guard let lineNumber = exception.objectForKeyedSubscript(\"line\"),\n            let column = exception.objectForKeyedSubscript(\"column\"),\n            let message = exception.objectForKeyedSubscript(\"message\"),\n            let stacktrace = exception.objectForKeyedSubscript(\"stack\")?.toString() else {\n                return print(\"Couldn't print stack trace\")\n        }\n        \n        if includeExceptionDescription {\n            print(\"JS Exception at \\(lineNumber):\\(column): \\(message)\")\n        }\n        \n        let lines = stacktrace.split(separator: \"\\n\").map { \"\\t> \\($0)\" }.joined(separator: \"\\n\")\n        print(lines)\n    }\n}\n\n#if !swift(>=3.2)\nextension String {\n    func split(separator: Character, omittingEmptySubsequences: Bool = true) -> [String] {\n        return characters.split(separator: separator, omittingEmptySubsequences: omittingEmptySubsequences).map(String.init)\n    }\n    \n    var first: Character? {\n        return characters.first\n    }\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "Tests/JS-A+/MockNodeEnvironment.swift",
    "content": "//\n//  MockNodeEnvironment.swift\n//  PMKJSA+Tests\n//\n//  Created by Lois Di Qual on 3/1/18.\n//\n\n#if swift(>=3.2) && !os(watchOS)\n\nimport Foundation\nimport JavaScriptCore\n\nclass MockNodeEnvironment {\n    \n    private var timers: [UInt32: Timer] = [:]\n    \n    func setup(with context: JSContext) {\n        \n        // console.log / console.error\n        setupConsole(context: context)\n        \n        // setTimeout\n        let setTimeout: @convention(block) (JSValue, Double) -> UInt32 = { function, intervalMs in\n            let timerID = self.addTimer(interval: intervalMs / 1000, repeats: false, function: function)\n            return timerID\n        }\n        context.setObject(setTimeout, forKeyedSubscript: \"setTimeout\" as NSString)\n        \n        // clearTimeout\n        let clearTimeout: @convention(block) (JSValue) -> Void = { timeoutID in\n            guard timeoutID.isNumber else {\n                return\n            }\n            self.removeTimer(timerID: timeoutID.toUInt32())\n        }\n        context.setObject(clearTimeout, forKeyedSubscript: \"clearTimeout\" as NSString)\n        \n        // setInterval\n        let setInterval: @convention(block) (JSValue, Double) -> UInt32 = { function, intervalMs in\n            let timerID = self.addTimer(interval: intervalMs / 1000, repeats: true, function: function)\n            return timerID\n        }\n        context.setObject(setInterval, forKeyedSubscript: \"setInterval\" as NSString)\n        \n        // clearInterval\n        let clearInterval: @convention(block) (JSValue) -> Void = { intervalID in\n            guard intervalID.isNumber else {\n                return\n            }\n            self.removeTimer(timerID: intervalID.toUInt32())\n        }\n        context.setObject(clearInterval, forKeyedSubscript: \"clearInterval\" as NSString)\n    }\n    \n    private func setupConsole(context: JSContext) {\n        \n        guard let console = context.objectForKeyedSubscript(\"console\") else {\n            fatalError(\"Couldn't get global `console` object\")\n        }\n        \n        let consoleLog: @convention(block) () -> Void = {\n            guard let arguments = JSContext.currentArguments(), let format = arguments.first as? JSValue else {\n                return\n            }\n            \n            let otherArguments = arguments.dropFirst()\n            if otherArguments.count == 0 {\n                print(format)\n            } else {\n                \n                let otherArguments = otherArguments.compactMap { $0 as? JSValue }\n                let format = format.toString().replacingOccurrences(of: \"%s\", with: \"%@\")\n                let expectedTypes = format.split(separator: \"%\", omittingEmptySubsequences: false).dropFirst().compactMap { $0.first }.map { String($0) }\n                \n                let typedArguments = otherArguments.enumerated().compactMap { index, value -> CVarArg? in\n                    let expectedType = expectedTypes[index]\n                    let converted: CVarArg\n                    switch expectedType {\n                    case \"s\": converted = value.toString()\n                    case \"d\": converted = value.toInt32()\n                    case \"f\": converted = value.toDouble()\n                    default: converted = value.toString()\n                    }\n                    return converted\n                }\n                \n                let output = String(format: format, arguments: typedArguments)\n                print(output)\n            }\n        }\n        console.setObject(consoleLog, forKeyedSubscript: \"log\" as NSString)\n        console.setObject(consoleLog, forKeyedSubscript: \"error\" as NSString)\n    }\n    \n    private func addTimer(interval: TimeInterval, repeats: Bool, function: JSValue) -> UInt32 {\n        let block = BlockOperation {\n            DispatchQueue.main.async {\n                function.call(withArguments: [])\n            }\n        }\n        let timer = Timer.scheduledTimer(timeInterval: interval, target: block, selector: #selector(Operation.main), userInfo: nil, repeats: repeats)\n        let rawHash = UUID().uuidString.hashValue\n    #if swift(>=4.0)\n        let hash = UInt32(truncatingIfNeeded: rawHash)\n    #else\n        let hash = UInt32(truncatingBitPattern: rawHash)\n    #endif\n        timers[hash] = timer\n        return hash\n    }\n    \n    private func removeTimer(timerID: UInt32) {\n        guard let timer = timers[timerID] else {\n            return print(\"Couldn't find timer \\(timerID)\")\n        }\n        timer.invalidate()\n        timers[timerID] = nil\n    }\n}\n\n\n#if swift(>=4.0) && !swift(>=4.1) || !swift(>=3.3)\nextension Sequence {\n    func compactMap<T>(_ transform: (Self.Element) throws -> T?) rethrows -> [T] {\n        return try flatMap(transform)\n    }\n}\n#endif\n#endif\n"
  },
  {
    "path": "Tests/JS-A+/README.md",
    "content": "Promises/A+ Compliance Test Suite (JavaScript)\n==============================================\n\nWhat is this?\n-------------\n\nThis contains the necessary Swift and JS files to run the Promises/A+ compliance test suite from PromiseKit's unit tests.\n\n - Promise/A+ Spec: <https://promisesaplus.com/>\n - Compliance Test Suite: <https://github.com/promises-aplus/promises-tests>\n\nRun tests\n---------\n\n```\n$ npm install\n$ npm run build\n```\n\nthen open `PromiseKit.xcodeproj` and run the `PMKJSA+Tests` unit test scheme.\n\nKnown limitations\n-----------------\n\nSee `ignoredTests` in `index.js`.\n\n\n - 2.3.3 is disabled: Otherwise, if x is an object or function. This spec is a NOOP for Swift:\n  - We have decided not to interact with other Promises A+ implementations\n  - functions cannot have properties\n\nUpgrade the test suite\n----------------------\n\n```\n$ npm install --save promises-aplus-tests@latest\n$ npm run build\n```\n\nDevelop\n-------\n\nJavaScriptCore is a bit tedious to work with so here are a couple tips in case you're trying to debug the test suite.\n\nIf you're editing JS files, enable live rebuilds:\n\n```\n$ npm run watch\n```\n\nIf you're editing Swift files, a couple things you can do:\n\n - You can adjust `testName` in `AllTests.swift` to only run one test suite\n - You can call `JSUtils.printCurrentStackTrace()` at any time. It won't contain line numbers but some of the frame names might help.\n\nHow it works\n------------\n\nThe Promises/A+ test suite is written in JavaScript but PromiseKit is written in Swift/ObjC. For the test suite to run against swift code, we expose a promise wrapper `JSPromise` inside a JavaScriptCore context. This is done in a regular XCTestCase.\n\nSince JavaScriptCore doesn't support CommonJS imports, we inline all the JavaScript code into `build/build.js` using webpack. This includes all the npm dependencies (`promises-aplus-tests`, `mocha`, `sinon`, etc) as well as the glue code in `index.js`.\n\n`build.js` exposes one global variable `runTests(adapter, onFail, onDone, [testName])`. In our XCTestCase, a shared JavaScriptCore context is created, `build.js` is evaluated and now `runTests` is accessible from the Swift context.\n\nIn our swift test, we create a JS-bridged `JSPromise` which only has one method `then(onFulfilled, onRejected) -> Promise`. It wraps a swift `Promise` and delegates call `then` calls to it.\n\nAn [adapter](https://github.com/promises-aplus/promises-tests#adapters) – plain JS object which provides `revoled(value), rejected(reason), and deferred()` – is passed to `runTests` to run the whole JavaScript test suite.\n\nErrors and end events are reported back to Swift and piped to `XCTFail()` if necessary.\n\nSince JavaScriptCore isn't a node/web environment, there is quite a bit of stubbing necessary for all this to work:\n\n - The `fs` module is stubbed with an empty function\n - `console.log` redirects to `Swift.print` and provides only basic format parsing\n - `setTimeout/setInterval` are implemented with `Swift.Timer` behind the scenes and stored in a `[TimerID: Timer]` map.\n"
  },
  {
    "path": "Tests/JS-A+/index.js",
    "content": "const _ = require('lodash')\nrequire('mocha')\n\n// Ignored by design\nconst ignoredTests = [\n  '2.3.3'\n]\n\nmodule.exports = function(adapter, onFail, onDone, testName) {\n  \n  global.adapter = adapter\n  const mocha = new Mocha({ ui: 'bdd' })\n\n  // Require all tests\n  console.log('Loading test files')\n  const requireTest = require.context('promises-aplus-tests/lib/tests', false, /\\.js$/)    \n  requireTest.keys().forEach(file => {\n    \n    let currentTestName = _.replace(_.replace(file, './', ''), '.js', '')\n    if (testName && currentTestName !== testName) {\n      return\n    }\n    \n    if (_.includes(ignoredTests, currentTestName)) {\n      return\n    }\n    \n    console.log(`\\t${currentTestName}`)\n    mocha.suite.emit('pre-require', global, file, mocha)\n    mocha.suite.emit('require', requireTest(file), file, mocha)\n    mocha.suite.emit('post-require', global, file, mocha)\n  })\n\n  const runner = mocha.run(failures => {\n    onDone(failures)\n  })\n  \n  runner.on('fail', (test, err) => {\n    console.error(err)\n    onFail(test.title, err)\n  })\n}\n"
  },
  {
    "path": "Tests/JS-A+/package.json",
    "content": "{\n  \"scripts\": {\n    \"build\": \"webpack-cli\",\n    \"watch\": \"webpack-cli --watch --mode development\"\n  },\n  \"dependencies\": {\n    \"babel-core\": \"^6.26.0\",\n    \"babel-loader\": \"^7.1.3\",\n    \"babel-preset-env\": \"^1.6.1\",\n    \"lodash\": \"^4.17.21\",\n    \"mocha\": \"^5.0.1\",\n    \"promises-aplus-tests\": \"^2.1.2\",\n    \"sinon\": \"^4.4.2\",\n    \"webpack\": \"^4.0.1\",\n    \"webpack-cli\": \"^2.0.9\"\n  }\n}\n"
  },
  {
    "path": "Tests/JS-A+/webpack.config.js",
    "content": "var webpack = require('webpack');\n\nmodule.exports = {\n  mode: 'development',\n  context: __dirname,\n  entry: './index.js',\n  output: {\n    path: __dirname + '/build',\n    filename: 'build.js',\n    library: 'runTests'\n  },\n  stats: {\n    warnings: false\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.js$/,\n        exclude: /(node_modules)/,\n        use: {\n          loader: 'babel-loader',\n          options: {\n            presets: ['env']\n          }\n        }\n      }\n    ]\n  },\n  node: {\n    fs: 'empty'\n  },\n};\n"
  },
  {
    "path": "Tests/LinuxMain.swift",
    "content": "import XCTest\n\nimport APlus\nimport CorePromise\n\nvar tests = [XCTestCaseEntry]()\ntests += APlus.__allTests()\ntests += CorePromise.__allTests()\n\nXCTMain(tests)\n"
  },
  {
    "path": "tea.yaml",
    "content": "# https://tea.xyz/what-is-this-file\n# created with https://mash.pkgx.sh/mxcl/tea-register\n---\nversion: 1.0.0\ncodeOwners:\n  - '0x5E2DE4A68df811AAAD32d71fb065e6946fA5C8d9'  # mxcl\nquorum: 1\n"
  }
]