diff --git a/.asf.yaml b/.asf.yaml
new file mode 100644
index 000000000..16a6e95c6
--- /dev/null
+++ b/.asf.yaml
@@ -0,0 +1,48 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+github:
+ description: Apache Cordova Media Plugin
+ homepage: https://cordova.apache.org/
+
+ labels:
+ - android
+ - cordova
+ - hacktoberfest
+ - ios
+ - java
+ - javascript
+ - library
+ - mobile
+ - nodejs
+ - objective-c
+
+ features:
+ wiki: false
+ issues: true
+ projects: true
+
+ enabled_merge_buttons:
+ squash: true
+ merge: false
+ rebase: false
+
+notifications:
+ commits: commits@cordova.apache.org
+ issues: issues@cordova.apache.org
+ pullrequests_status: issues@cordova.apache.org
+ pullrequests_comment: issues@cordova.apache.org
diff --git a/.eslintrc.yml b/.eslintrc.yml
new file mode 100644
index 000000000..b7281e68c
--- /dev/null
+++ b/.eslintrc.yml
@@ -0,0 +1,27 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+root: true
+extends: "@cordova/eslint-config/browser"
+rules:
+ no-var: 0
+
+overrides:
+ - files: [tests/**/*.js]
+ extends: "@cordova/eslint-config/node-tests"
+ rules:
+ no-var: 0
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 000000000..07764a78d
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+* text eol=lf
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 000000000..3220c258b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,42 @@
+
+
+### Issue Type
+
+
+- [ ] Bug Report
+- [ ] Feature Request
+- [ ] Support Question
+
+## Description
+
+## Information
+
+
+### Command or Code
+
+
+### Environment, Platform, Device
+
+
+
+
+### Version information
+
+
+
+
+## Checklist
+
+
+- [ ] I searched for already existing GitHub issues about this
+- [ ] I updated all Cordova tooling to their most recent version
+- [ ] I included all the necessary information above
diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md
new file mode 100644
index 000000000..bd8a3acb3
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.md
@@ -0,0 +1,50 @@
+---
+name: 🐛 Bug Report
+about: If something isn't working as expected.
+
+---
+
+# Bug Report
+
+## Problem
+
+### What is expected to happen?
+
+
+
+### What does actually happen?
+
+
+
+## Information
+
+
+
+
+### Command or Code
+
+
+
+
+### Environment, Platform, Device
+
+
+
+
+### Version information
+
+
+
+
+## Checklist
+
+
+- [ ] I searched for existing GitHub issues
+- [ ] I updated all Cordova tooling to most recent version
+- [ ] I included all the necessary information above
diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
new file mode 100644
index 000000000..381fc8a3b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
@@ -0,0 +1,29 @@
+---
+name: 🚀 Feature Request
+about: A suggestion for a new functionality
+
+---
+
+# Feature Request
+
+## Motivation Behind Feature
+
+
+
+
+## Feature Description
+
+
+
+
+## Alternatives or Workarounds
+
+
+
diff --git a/.github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md b/.github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md
new file mode 100644
index 000000000..516c6e6b9
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md
@@ -0,0 +1,27 @@
+---
+name: 💬 Support Question
+about: If you have a question, please check out our Slack or StackOverflow!
+
+---
+
+
+
+Apache Cordova uses GitHub Issues as a feature request and bug tracker _only_.
+For usage and support questions, please check out the resources below. Thanks!
+
+---
+
+You can get answers to your usage and support questions about **Apache Cordova** on:
+
+* Slack Community Chat: https://cordova.slack.com (you can sign-up at http://slack.cordova.io/)
+* StackOverflow: https://stackoverflow.com/questions/tagged/cordova using the tag `cordova`
+
+---
+
+If you are using a tool that uses Cordova internally, like e.g. Ionic, check their support channels:
+
+* **Ionic Framework**
+ * [Ionic Community Forum](https://forum.ionicframework.com/)
+ * [Ionic Worldwide Slack](https://ionicworldwide.herokuapp.com/)
+* **PhoneGap**
+ * [PhoneGap Developer Community](https://forums.adobe.com/community/phonegap)
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 4bd6da9d0..712b2ff04 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,6 +1,5 @@
+
+
+
+
+### Description
+
+
+
+
+### Testing
+
-### What testing has been done on this change?
### Checklist
-- [ ] [ICLA](http://www.apache.org/licenses/icla.txt) has been signed and submitted to secretary@apache.org.
-- [ ] [Reported an issue](http://cordova.apache.org/contribute/issues.html) in the JIRA database
-- [ ] Commit message follows the format: "CB-3232: (android) Fix bug with resolving file paths", where CB-xxxx is the JIRA ID & "android" is the platform affected.
-- [ ] Added automated test coverage as appropriate for this change.
+
+- [ ] I've run the tests to see all new and existing tests pass
+- [ ] I added automated test coverage as appropriate for this change
+- [ ] Commit is prefixed with `(platform)` if this change only applies to one platform (e.g. `(android)`)
+- [ ] If this Pull Request resolves an issue, I linked to the issue in the text above (and used the correct [keyword to close issues using keywords](https://help.github.com/articles/closing-issues-using-keywords/))
+- [ ] I've updated the documentation if necessary
diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml
new file mode 100644
index 000000000..2d17c4079
--- /dev/null
+++ b/.github/workflows/android.yml
@@ -0,0 +1,161 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Android Testsuite
+
+on:
+ push:
+ paths-ignore:
+ - '**.md'
+ - 'LICENSE'
+ - '.eslint*'
+
+ pull_request:
+ paths-ignore:
+ - '**.md'
+ - 'LICENSE'
+ - '.eslint*'
+
+jobs:
+ test:
+ name: Android ${{ matrix.versions.android }} Test
+ runs-on: ubuntu-latest
+ continue-on-error: true
+
+ # hoist configurations to top that are expected to be updated
+ env:
+ # Storing a copy of the repo
+ repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
+
+ node-version: 20
+
+ # These are the default Java configurations used by most tests.
+ # To customize these options, add "java-distro" or "java-version" to the strategy matrix with its overriding value.
+ default_java-distro: temurin
+ default_java-version: 17
+
+ # These are the default Android System Image configurations used by most tests.
+ # To customize these options, add "system-image-arch" or "system-image-target" to the strategy matrix with its overriding value.
+ default_system-image-arch: x86_64
+ default_system-image-target: google_apis # Most system images have a google_api option. Set this as default.
+
+ # configurations for each testing strategy (test matrix)
+ strategy:
+ matrix:
+ versions:
+ - android: 7
+ android-api: 24
+
+ - android: 7.1
+ android-api: 25
+
+ - android: 8
+ android-api: 26
+
+ - android: 8.1
+ android-api: 27
+ system-image-arch: x86
+
+ - android: 9
+ android-api: 28
+
+ - android: 10
+ android-api: 29
+
+ - android: 11
+ android-api: 30
+
+ - android: 12
+ android-api: 31
+
+ - android: 12L
+ android-api: 32
+
+ - android: 13
+ android-api: 33
+
+ - android: 14
+ android-api: 34
+
+ timeout-minutes: 60
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.node-version }}
+ - uses: actions/setup-java@v4
+ env:
+ java-version: ${{ matrix.versions.java-version == '' && env.default_java-version || matrix.versions.java-version }}
+ java-distro: ${{ matrix.versions.java-distro == '' && env.default_java-distro || matrix.versions.java-distro }}
+ with:
+ distribution: ${{ env.java-distro }}
+ java-version: ${{ env.java-version }}
+
+ - name: Enable KVM group perms
+ run: |
+ echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
+ sudo udevadm control --reload-rules
+ sudo udevadm trigger --name-match=kvm
+
+ - name: Run Environment Information
+ run: |
+ node --version
+ npm --version
+ java -version
+
+ - name: Run npm install
+ run: |
+ export PATH="/usr/local/lib/android/sdk/platform-tools":$PATH
+ export JAVA_HOME=$JAVA_HOME_11_X64
+ npm i -g cordova@latest
+ npm ci
+
+ - name: Run paramedic install
+ if: ${{ endswith(env.repo, '/cordova-paramedic') != true }}
+ run: npm i -g github:apache/cordova-paramedic
+
+ - uses: reactivecircus/android-emulator-runner@v2
+ env:
+ system-image-arch: ${{ matrix.versions.system-image-arch == '' && env.default_system-image-arch || matrix.versions.system-image-arch }}
+ system-image-target: ${{ matrix.versions.system-image-target == '' && env.default_system-image-target || matrix.versions.system-image-target }}
+ with:
+ api-level: ${{ matrix.versions.android-api }}
+ target: ${{ env.system-image-target }}
+ arch: ${{ env.system-image-arch }}
+ force-avd-creation: false
+ disable-animations: false
+ emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim
+ script: echo "Pregenerate the AVD before running Paramedic"
+
+ - name: Run paramedic tests
+ uses: reactivecircus/android-emulator-runner@v2
+ env:
+ system-image-arch: ${{ matrix.versions.system-image-arch == '' && env.default_system-image-arch || matrix.versions.system-image-arch }}
+ system-image-target: ${{ matrix.versions.system-image-target == '' && env.default_system-image-target || matrix.versions.system-image-target }}
+ test_config: 'android-${{ matrix.versions.android }}.config.json'
+ # Generally, this should automatically work for cordova-paramedic & plugins. If the path is unique, this can be manually changed.
+ test_plugin_path: ${{ endswith(env.repo, '/cordova-paramedic') && './spec/testable-plugin/' || './' }}
+ paramedic: ${{ endswith(env.repo, '/cordova-paramedic') && 'node main.js' || 'cordova-paramedic' }}
+ with:
+ api-level: ${{ matrix.versions.android-api }}
+ target: ${{ env.system-image-target }}
+ arch: ${{ env.system-image-arch }}
+ force-avd-creation: false
+ disable-animations: false
+ emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim
+ script: ${{ env.paramedic }} --config ./pr/local/${{ env.test_config }} --plugin ${{ env.test_plugin_path }}
diff --git a/.github/workflows/chrome.yml b/.github/workflows/chrome.yml
new file mode 100644
index 000000000..a067f6541
--- /dev/null
+++ b/.github/workflows/chrome.yml
@@ -0,0 +1,73 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Chrome Testsuite
+
+on:
+ push:
+ paths-ignore:
+ - '**.md'
+ - 'LICENSE'
+ - '.eslint*'
+ pull_request:
+ paths-ignore:
+ - '**.md'
+ - 'LICENSE'
+ - '.eslint*'
+
+jobs:
+ test:
+ name: Chrome Latest Test
+ runs-on: ubuntu-latest
+
+ # hoist configurations to top that are expected to be updated
+ env:
+ # Storing a copy of the repo
+ repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
+
+ node-version: 20
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.node-version }}
+
+ - name: Run install xvfb
+ run: sudo apt-get install xvfb
+
+ - name: Run Environment Information
+ run: |
+ node --version
+ npm --version
+
+ - name: Run npm install
+ run: |
+ npm i -g cordova@latest
+ npm ci
+
+ - name: Run paramedic install
+ if: ${{ endswith(env.repo, '/cordova-paramedic') != true }}
+ run: npm i -g github:apache/cordova-paramedic
+
+ - name: Run paramedic tests
+ env:
+ test_config: 'browser.config.json'
+ # Generally, this should automatically work for cordova-paramedic & plugins. If the path is unique, this can be manually changed.
+ test_plugin_path: ${{ endswith(env.repo, '/cordova-paramedic') && './spec/testable-plugin/' || './' }}
+ paramedic: ${{ endswith(env.repo, '/cordova-paramedic') && 'node main.js' || 'cordova-paramedic' }}
+ run: xvfb-run --auto-servernum ${{ env.paramedic }} --config ./pr/local/${{ env.test_config }} --plugin ${{ env.test_plugin_path }}
diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml
new file mode 100644
index 000000000..aa2e7ef41
--- /dev/null
+++ b/.github/workflows/ios.yml
@@ -0,0 +1,97 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: iOS Testsuite
+
+on:
+ push:
+ paths-ignore:
+ - '**.md'
+ - 'LICENSE'
+ - '.eslint*'
+ pull_request:
+ paths-ignore:
+ - '**.md'
+ - 'LICENSE'
+ - '.eslint*'
+
+jobs:
+ test:
+ name: iOS ${{ matrix.versions.ios-version }} Test
+ runs-on: ${{ matrix.versions.os-version }}
+ continue-on-error: true
+
+ # hoist configurations to top that are expected to be updated
+ env:
+ # Storing a copy of the repo
+ repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
+
+ node-version: 20
+
+ # > Starting April 26, 2021, all iOS and iPadOS apps submitted to the App Store must be built with Xcode 12 and the iOS 14 SDK.
+ # Because of Apple's requirement, listed above, We will only be using the latest Xcode release for testing.
+ # To customize these options, add "xcode-version" to the strategy matrix with its overriding value.
+ default_xcode-version: latest-stable
+
+ strategy:
+ matrix:
+ versions:
+ - os-version: macos-12
+ ios-version: 15.x
+ xcode-version: 13.x
+
+ - os-version: macos-14
+ ios-version: 16.x
+ xcode-version: 14.x
+
+ - os-version: macos-14
+ ios-version: 17.x
+ xcode-version: 15.x
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.node-version }}
+ - uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd
+ env:
+ xcode-version: ${{ matrix.versions.xcode-version == '' && env.default_xcode-version || matrix.versions.xcode-version }}
+ with:
+ xcode-version: ${{ env.xcode-version }}
+
+ - name: Run Environment Information
+ run: |
+ node --version
+ npm --version
+ xcodebuild -version
+
+ - name: Run npm install
+ run: |
+ npm i -g cordova@latest ios-deploy@latest
+ npm ci
+
+ - name: Run paramedic install
+ if: ${{ endswith(env.repo, '/cordova-paramedic') != true }}
+ run: npm i -g github:apache/cordova-paramedic
+
+ - name: Run paramedic tests
+ env:
+ test_config: 'ios-${{ matrix.versions.ios-version }}.config.json'
+ # Generally, this should automatically work for cordova-paramedic & plugins. If the path is unique, this can be manually changed.
+ test_plugin_path: ${{ endswith(env.repo, '/cordova-paramedic') && './spec/testable-plugin/' || './' }}
+ paramedic: ${{ endswith(env.repo, '/cordova-paramedic') && 'node main.js' || 'cordova-paramedic' }}
+ run: ${{ env.paramedic }} --config ./pr/local/${{ env.test_config }} --plugin ${{ env.test_plugin_path }}
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 000000000..53dad12fd
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,56 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Lint Test
+
+on:
+ push:
+ paths:
+ - '**.js'
+ - '.eslint*'
+ - '.github/workflow/lint.yml'
+ pull_request:
+ paths:
+ - '**.js'
+ - '.eslint*'
+ - '.github/workflow/lint.yml'
+
+jobs:
+ test:
+ name: Lint Test
+ runs-on: ubuntu-latest
+ env:
+ node-version: 20
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.node-version }}
+
+ - name: Run Environment Information
+ run: |
+ node --version
+ npm --version
+
+ - name: Run npm install
+ run: |
+ npm ci
+
+ - name: Run lint test
+ run: |
+ npm run lint
diff --git a/.gitignore b/.gitignore
index 6964ea05b..ed83a7afa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,10 +14,13 @@ Thumbs.db
node_modules
+#eclipse
+bin
+.project
+.classpath
-
-
\ No newline at end of file
+
diff --git a/.jshintrc b/.jshintrc
deleted file mode 100644
index df3248213..000000000
--- a/.jshintrc
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "browser": true
- , "devel": true
- , "bitwise": true
- , "undef": true
- , "trailing": true
- , "quotmark": false
- , "indent": 4
- , "unused": "vars"
- , "latedef": "nofunc"
- , "globals": {
- "module": false,
- "exports": false,
- "require": false,
- "cordova": true
- }
-}
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 000000000..2657abf2a
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,2 @@
+.*
+tests
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index b9af4c58b..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-language: node_js
-sudo: false
-node_js:
- - "4.2"
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4c8e6a5ea..21a93d72a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -25,13 +25,13 @@ Anyone can contribute to Cordova. And we need your contributions.
There are multiple ways to contribute: report bugs, improve the docs, and
contribute code.
-
-For instructions on this, start with the
+
+For instructions on this, start with the
[contribution overview](http://cordova.apache.org/contribute/).
The details are explained there, but the important items are:
- - Sign and submit an Apache ICLA (Contributor License Agreement).
- - Have a Jira issue open that corresponds to your contribution.
+ - Check for Github issues that corresponds to your contribution and link or create them if necessary.
- Run the tests so your patch doesn't break existing functionality.
We look forward to your contributions!
+
diff --git a/README.md b/README.md
index 818889a0d..0e629ffc9 100644
--- a/README.md
+++ b/README.md
@@ -21,12 +21,10 @@ description: Record and play audio on the device.
# under the License.
-->
-|Android|iOS| Windows 8.1 Store | Windows 8.1 Phone | Windows 10 Store | Travis CI |
-|:-:|:-:|:-:|:-:|:-:|:-:|
-|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=android,PLUGIN=cordova-plugin-media/)|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=ios,PLUGIN=cordova-plugin-media/)|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=windows-8.1-store,PLUGIN=cordova-plugin-media/)|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=windows-8.1-phone,PLUGIN=cordova-plugin-media/)|[](http://cordova-ci.cloudapp.net:8080/job/cordova-periodic-build/PLATFORM=windows-10-store,PLUGIN=cordova-plugin-media/)|[](https://travis-ci.org/apache/cordova-plugin-media)|
-
# cordova-plugin-media
+[](https://github.com/apache/cordova-plugin-media/actions/workflows/android.yml) [](https://github.com/apache/cordova-plugin-media/actions/workflows/chrome.yml) [](https://github.com/apache/cordova-plugin-media/actions/workflows/ios.yml) [](https://github.com/apache/cordova-plugin-media/actions/workflows/lint.yml)
+
This plugin provides the ability to record and play back audio files on a device.
@@ -46,9 +44,6 @@ function onDeviceReady() {
}
```
-Report issues with this plugin on the [Apache Cordova issue tracker](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CB%20AND%20status%20in%20%28Open%2C%20%22In%20Progress%22%2C%20Reopened%29%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20%22Plugin%20Media%22%20ORDER%20BY%20priority%20DESC%2C%20summary%20ASC%2C%20updatedDate%20DESC)
-
-
## Installation
```bash
@@ -58,17 +53,24 @@ cordova plugin add cordova-plugin-media
## Supported Platforms
- Android
-- BlackBerry 10
- iOS
-- Windows Phone 7 and 8
-- Tizen
-- Windows 8
-- Windows
- Browser
-## Windows Phone Quirks
+### Android Quirks
+
+#### SDK Target Less Than 29
-- Only one media file can be played back at a time.
+From the official [Storage updates in Android 11](https://developer.android.com/about/versions/11/privacy/storage) documentation, the [`WRITE_EXTERNAL_STORAGE`](https://developer.android.com/reference/android/Manifest.permission#WRITE_EXTERNAL_STORAGE) permission is no longer operational and does not provide access.
+
+> If this permission is not allowlisted for an app that targets an API level before [`Build.VERSION_CODES.Q`](https://developer.android.com/reference/android/os/Build.VERSION_CODES#Q) (SDK 29) this permission cannot be granted to apps.
+
+If you need to add this permission, please add the following to your `config.xml`.
+
+```xml
+
+
+
+```
## Media
@@ -82,9 +84,11 @@ var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
- __mediaSuccess__: (Optional) The callback that executes after a `Media` object has completed the current play, record, or stop action. _(Function)_
-- __mediaError__: (Optional) The callback that executes if an error occurs. _(Function)_
+- __mediaError__: (Optional) The callback that executes if an error occurs. It takes an integer error code. _(Function)_
+
+- __mediaStatus__: (Optional) The callback that executes to indicate status changes. It takes a integer status code. _(Function)_
-- __mediaStatus__: (Optional) The callback that executes to indicate status changes. _(Function)_
+- __mediaDurationUpdate__: (Optional) the callback that executes when the file's duration updates and is available. _(Function)_
__NOTE__: `cdvfile` path is supported as `src` parameter:
```javascript
@@ -104,7 +108,7 @@ The following constants are reported as the only parameter to the
### Methods
-- `media.getCurrentAmplitude`: Returns the current position within an audio file.
+- `media.getCurrentAmplitude`: Returns the current amplitude within an audio file.
- `media.getCurrentPosition`: Returns the current position within an audio file.
@@ -130,6 +134,8 @@ The following constants are reported as the only parameter to the
- `media.stop`: Stop playing an audio file.
+- `media.setRate`: Set the playback rate for the audio file.
+
### Additional ReadOnly Parameters
- __position__: The position within the audio playback, in seconds.
@@ -140,7 +146,7 @@ The following constants are reported as the only parameter to the
## media.getCurrentAmplitude
-Returns the current amplitude of the current recording.
+Returns the current amplitude within an audio file.
media.getCurrentAmplitude(mediaSuccess, [mediaError]);
@@ -246,6 +252,10 @@ var timerDur = setInterval(function() {
}, 100);
```
+#### Android Quirk
+
+Newer versions of Android have aggressive routines that limit background processing. If you are trying to get the duration while your app is in the background longer than roughly 5 minutes, you will get more consistent results by using the [`mediaDurationUpdate` callback of the constructor](#parameters).
+
## media.pause
Pauses playing an audio file.
@@ -312,7 +322,7 @@ function recordAudio() {
// Pause Recording after 5 seconds
setTimeout(function() {
- my_media.pauseRecord();
+ mediaRec.pauseRecord();
}, 5000);
}
```
@@ -360,8 +370,11 @@ function playAudio(url) {
is locked. If set to `true` (the default value), the state of the
hardware mute button is ignored, e.g.:
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
+ var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3");
+ myMedia.play({ playAudioWhenScreenIsLocked : true });
+ myMedia.setVolume('1.0');
+
+> Note: To allow playback with the screen locked or background audio you have to add `audio` to `UIBackgroundModes` in the `info.plist` file. See [Apple documentation](https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html#//apple_ref/doc/uid/TP40007072-CH4-SW23). Also note that the audio has to be started before going to background.
- __order of file search__: When only a file name or simple path is
provided, iOS searches in the `www` directory for the file, then in
@@ -427,12 +440,12 @@ function recordAudio() {
// Pause Recording after 5 seconds
setTimeout(function() {
- my_media.pauseRecord();
+ mediaRec.pauseRecord();
}, 5000);
// Resume Recording after 10 seconds
setTimeout(function() {
- my_media.resumeRecord();
+ mediaRec.resumeRecord();
}, 10000);
}
```
@@ -461,10 +474,6 @@ setTimeout(function() {
}, 5000);
```
-### BlackBerry 10 Quirks
-
-- Not supported on BlackBerry OS 5 devices.
-
## media.setVolume
Set the volume for an audio file.
@@ -522,8 +531,6 @@ Starts recording an audio file.
- Android
- iOS
-- Windows Phone 7 and 8
-- Windows
### Quick Example
@@ -550,12 +557,12 @@ function recordAudio() {
### Android Quirks
-- Android devices record audio in Adaptive Multi-Rate format. The specified file should end with a _.amr_ extension.
+- Android devices record audio in AAC ADTS file format. The specified file should end with a _.aac_ extension.
- The hardware volume controls are wired up to the media volume while any Media objects are alive. Once the last created Media object has `release()` called on it, the volume controls revert to their default behaviour. The controls are also reset on page navigation, as this releases all Media objects.
### iOS Quirks
-- iOS only records to files of type _.wav_ and returns an error if the file name extension is not correct.
+- iOS only records to files of type _.wav_ and _.m4a_ and returns an error if the file name extension is not correct.
- If a full path is not provided, the recording is placed in the application's `documents/tmp` directory. This can be accessed via the `File` API using `LocalFileSystem.TEMPORARY`. Any subdirectory specified at record time must already exist.
@@ -563,17 +570,19 @@ function recordAudio() {
var myMedia = new Media("documents://beer.mp3")
-### Windows Quirks
-
-- Windows devices can use MP3, M4A and WMA formats for recorded audio. However in most cases it is not possible to use MP3 for audio recording on _Windows Phone 8.1_ devices, because an MP3 encoder is [not shipped with Windows Phone](https://msdn.microsoft.com/en-us/library/windows/apps/windows.media.mediaproperties.mediaencodingprofile.createmp3.aspx).
+- Since iOS 10 it's mandatory to provide an usage description in the `info.plist` if trying to access privacy-sensitive data. When the system prompts the user to allow access, this usage description string will displayed as part of the permission dialog box, but if you didn't provide the usage description, the app will crash before showing the dialog. Also, Apple will reject apps that access private data but don't provide an usage description.
-- If a full path is not provided, the recording is placed in the `AppData/temp` directory. This can be accessed via the `File` API using `LocalFileSystem.TEMPORARY` or `ms-appdata:///temp/` URI.
+This plugins requires the following usage description:
-- Any subdirectory specified at record time must already exist.
+* `NSMicrophoneUsageDescription` describes the reason that the app accesses the user's microphone.
-### Tizen Quirks
+To add this entry into the `info.plist`, you can use the `edit-config` tag in the `config.xml` like this:
-- Not supported on Tizen devices.
+```
+
+ need microphone access to record sounds
+
+```
## media.stop
@@ -619,8 +628,6 @@ Stops recording an audio file.
- Android
- iOS
-- Windows Phone 7 and 8
-- Windows
### Quick Example
@@ -651,9 +658,34 @@ function recordAudio() {
}
```
-### Tizen Quirks
+## media.setRate
-- Not supported on Tizen devices.
+Stops recording an audio file.
+
+ media.setRate(rate);
+
+### Supported Platforms
+
+- iOS
+- Android (API 23+)
+
+### Parameters
+
+- __rate__: The rate to set for playback.
+
+### Quick Example
+
+```js
+// Audio player
+//
+var my_media = new Media(src, onSuccess, onError);
+ my_media.play();
+
+// Set playback rate to 2.0x after 10 seconds
+setTimeout(function() {
+ my_media.setRate(2.0);
+}, 5000);
+```
## MediaError
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 0ccca54fe..c42ef2f0d 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -20,6 +20,141 @@
-->
# Release Notes
+### 7.0.0 (Sep 07, 2023)
+
+**Breaking Changes:**
+
+* [GH-384](https://github.com/apache/cordova-plugin-media/pull/384) fix!: remove deprecated `windows` platform
+* [GH-378](https://github.com/apache/cordova-plugin-media/pull/378) feat(android)!: bump file & **Android** requirements
+
+**Features:**
+
+* [GH-362](https://github.com/apache/cordova-plugin-media/pull/362) feat(ios): load media files with custom scheme+hostname and leading directory paths
+* [GH-383](https://github.com/apache/cordova-plugin-media/pull/383) feat(android): increase audio encoding bitrate and sampling rate
+* [GH-382](https://github.com/apache/cordova-plugin-media/pull/382) feat(android): support Android 13 permission checks and requests
+
+**Others:**
+
+* [GH-381](https://github.com/apache/cordova-plugin-media/pull/381) dep(dev)!: bump `@cordova/eslint-config@5.0.0`
+* [GH-377](https://github.com/apache/cordova-plugin-media/pull/377) ci: sync github action workflow w/ paramedic base configs
+
+### 6.1.0 (Sep 06, 2022)
+
+* [GH-357](https://github.com/apache/cordova-plugin-media/pull/357) feat(android): add '`message`' field to media error [CB-11641](https://issues.apache.org/jira/browse/CB-11641)
+* [GH-352](https://github.com/apache/cordova-plugin-media/pull/352) feat(ios): support `file` scheme
+* [GH-354](https://github.com/apache/cordova-plugin-media/pull/354) fix(ios): Reset default audio session category when release ([CB-13243](https://issues.apache.org/jira/browse/CB-13243))
+* [GH-353](https://github.com/apache/cordova-plugin-media/pull/353) fix(ios): error on `getPosition` when time is `nan`
+* [GH-355](https://github.com/apache/cordova-plugin-media/pull/355) test(spec.22): pause media before calling `getCurrentPosition`
+* [GH-356](https://github.com/apache/cordova-plugin-media/pull/356) test(spec.timeout): try to improve against timeout failures
+* [GH-351](https://github.com/apache/cordova-plugin-media/pull/351) ci: sync workflow with paramedic
+* [GH-349](https://github.com/apache/cordova-plugin-media/pull/349) ci(android): update java requirement for `cordova-android@11`
+
+### 6.0.0 (May 25, 2022)
+
+* [GH-344](https://github.com/apache/cordova-plugin-media/pull/344) feat(android): drop `WRITE_EXTERNAL_STORAGE` permission
+* [GH-195](https://github.com/apache/cordova-plugin-media/pull/195) feat(ios): Add error call for `stalled_playback`
+* [GH-341](https://github.com/apache/cordova-plugin-media/pull/341) feat(android): add `setRate`
+* [GH-340](https://github.com/apache/cordova-plugin-media/pull/340) fix(ios): set rate with current playback rate
+* [GH-197](https://github.com/apache/cordova-plugin-media/pull/197) feat: add `durationUpdate` callback
+* [GH-232](https://github.com/apache/cordova-plugin-media/pull/232) fix(android): remove `READ_PHONE_STATE` permission
+* [GH-285](https://github.com/apache/cordova-plugin-media/pull/285) fix: remove deprecated platform code snippets
+* [GH-338](https://github.com/apache/cordova-plugin-media/pull/338) fix: missing parenthesis from #328
+* [GH-328](https://github.com/apache/cordova-plugin-media/pull/328) fix(android): issue #325
+* [GH-334](https://github.com/apache/cordova-plugin-media/pull/334) dep!: bump `cordova-plugin-file@^7.0.0`
+* [GH-337](https://github.com/apache/cordova-plugin-media/pull/337) chore: bump `cordovaDependencies` next next major cordova requirement
+* [GH-336](https://github.com/apache/cordova-plugin-media/pull/336) chore: rebuilt `package-lock`
+
+### 5.0.4 (Jan 21, 2022)
+
+* [GH-329](https://github.com/apache/cordova-plugin-media/pull/329) dep: bump `@cordova/eslint-config@4.0.0` w/ fix & `package-lock` rebuild
+* [GH-317](https://github.com/apache/cordova-plugin-media/pull/317) fix(android): get external files directory for **Android** 10+
+* [GH-320](https://github.com/apache/cordova-plugin-media/pull/320) ci(ios): update workflow w/ **iOS** 15
+* [GH-318](https://github.com/apache/cordova-plugin-media/pull/318) test(browser): disable test cases w/ play() due to Chrome's Autoplay Policy
+* [GH-313](https://github.com/apache/cordova-plugin-media/pull/313) ci: add action-badge
+* [GH-312](https://github.com/apache/cordova-plugin-media/pull/312) ci: remove travis & appveyor
+* [GH-311](https://github.com/apache/cordova-plugin-media/pull/311) ci: add gh-actions workflows
+* [GH-298](https://github.com/apache/cordova-plugin-media/pull/298) ci: add node-14.x to workflow
+* [GH-292](https://github.com/apache/cordova-plugin-media/pull/292) ci(travis): update osx xcode image
+* [GH-291](https://github.com/apache/cordova-plugin-media/pull/291) ci(travis): updates **Android** API level
+* [GH-284](https://github.com/apache/cordova-plugin-media/pull/284) chore: adds `package-lock` file
+* [GH-283](https://github.com/apache/cordova-plugin-media/pull/283) refactor(eslint): use `cordova-eslint` /w fix
+* [GH-282](https://github.com/apache/cordova-plugin-media/pull/282) chore(npm): use short notation in `package.json`
+* chore(asf): update git notification settings
+* Update CONTRIBUTING.md
+* [GH-249](https://github.com/apache/cordova-plugin-media/pull/249) Fix #248 delete javascript reference to released media
+* [GH-274](https://github.com/apache/cordova-plugin-media/pull/274) ci: updates Node.js versions
+* [GH-275](https://github.com/apache/cordova-plugin-media/pull/275) chore(npm): improve ignore list
+* ci(travis): upgrade to node8
+* [GH-241](https://github.com/apache/cordova-plugin-media/pull/241) fix(types): Add type definition for getCurrentAmplitude
+
+### 5.0.3 (Jun 27, 2019)
+
+- chore: fix repo and issue urls and license in package.json and plugin.xml ([`784ac7b`](https://github.com/apache/cordova-plugin-media/commit/784ac7b))
+- build: add `.gitattributes` to force LF (instead of possible CRLF on Windows) ([`5244c4a`](https://github.com/apache/cordova-plugin-media/commit/5244c4a))
+- build: add `.npmignore` to remove unneeded files from npm package ([`aa1586d`](https://github.com/apache/cordova-plugin-media/commit/aa1586d))
+- ci(travis): Update Travis CI configuration for new paramedic ([#227](https://github.com/apache/cordova-plugin-media/issues/227)) ([`b0ed6bd`](https://github.com/apache/cordova-plugin-media/commit/b0ed6bd))
+- chore(github): Add or update GitHub pull request and issue template ([`b1c1353`](https://github.com/apache/cordova-plugin-media/commit/b1c1353))
+- docs: remove JIRA link ([`2acd3c2`](https://github.com/apache/cordova-plugin-media/commit/2acd3c2))
+- ci(travis): also accept terms for android sdk `android-27` ([`74772c3`](https://github.com/apache/cordova-plugin-media/commit/74772c3))
+- docs: remove outdated docs that haven't been updated for 3 years ([`a006da3`](https://github.com/apache/cordova-plugin-media/commit/a006da3))
+- fix(types): add types for callback in constructor ([#90](https://github.com/apache/cordova-plugin-media/issues/90)) ([`7094582`](https://github.com/apache/cordova-plugin-media/commit/7094582))
+- docs: (iOS) document setRate method ([#142](https://github.com/apache/cordova-plugin-media/issues/142)) ([`5f18902`](https://github.com/apache/cordova-plugin-media/commit/5f18902))
+- fix(ios): [CB-13445](https://issues.apache.org/jira/browse/CB-13445) (iOS) Streaming media can take up to 8-10 seconds to start ([#169](https://github.com/apache/cordova-plugin-media/issues/169)) ([`43d57ca`](https://github.com/apache/cordova-plugin-media/commit/43d57ca))
+- fix(android): [CB-12849](https://issues.apache.org/jira/browse/CB-12849) checking mediaState in destroy method, and moving file by stream when renameTo failing ([#168](https://github.com/apache/cordova-plugin-media/issues/168)) ([`86660dd`](https://github.com/apache/cordova-plugin-media/commit/86660dd))
+- tests: [CB-14091](https://issues.apache.org/jira/browse/CB-14091) fix tests code for stream url and remove browser ([#166](https://github.com/apache/cordova-plugin-media/issues/166)) ([`524c337`](https://github.com/apache/cordova-plugin-media/commit/524c337))
+
+
+### 5.0.2 (Jan 24, 2018)
+* [CB-13751](https://issues.apache.org/jira/browse/CB-13751) Add build-tools-26.0.2 to travis (#163)
+* Fix for [CB-11513](https://issues.apache.org/jira/browse/CB-11513)
+* [CB-7684](https://issues.apache.org/jira/browse/CB-7684) (#143)
+
+### 5.0.1 (Dec 27, 2017)
+* [CB-13706](https://issues.apache.org/jira/browse/CB-13706) Fix to allow 5.0.0 version install (#160)
+* Bump cordova-plugin-file dependency to 6.0.0
+
+### 5.0.0 (Dec 15, 2017)
+* [CB-13678](https://issues.apache.org/jira/browse/CB-13678) Remove deprecated platforms
+
+### 4.0.0 (Nov 06, 2017)
+* [CB-12264](https://issues.apache.org/jira/browse/CB-12264) (README): fix `media.getCurrentAmplitude` definition
+* [CB-13265](https://issues.apache.org/jira/browse/CB-13265) Remove **iOS** usage description from media plugin
+* [CB-13517](https://issues.apache.org/jira/browse/CB-13517) (all): Add 'protective' entry to `cordovaDependencies`
+* [CB-13473](https://issues.apache.org/jira/browse/CB-13473) (CI) Removed **Browser** builds from AppVeyor
+* [CB-13294](https://issues.apache.org/jira/browse/CB-13294) Remove `cordova-plugin-compat`
+* [CB-13299](https://issues.apache.org/jira/browse/CB-13299) (CI) Fix **Android** builds
+* [CB-13028](https://issues.apache.org/jira/browse/CB-13028) (CI) **Browser** builds on Travis and AppVeyor
+* [CB-12671](https://issues.apache.org/jira/browse/CB-12671) **iOS**: Fix auto-test with stopping media that is in starting state
+* [CB-12847](https://issues.apache.org/jira/browse/CB-12847) added `bugs` entry to `package.json`.
+
+### 3.0.1 (Apr 27, 2017)
+* [CB-12542](https://issues.apache.org/jira/browse/CB-12542) (ios) Fix wav file recording, add m4a extension. make **iOS** status handling compatible with **Android**/Windows
+* [CB-12622](https://issues.apache.org/jira/browse/CB-12622) Added **Android 6.0** build badges to `README`
+* [CB-12685](https://issues.apache.org/jira/browse/CB-12685) added `package.json` to tests folder
+
+### 3.0.0 (Feb 28, 2017)
+* **Android:** fix `NullPointerException` in `AudioPlayer.readyPlayer`
+* **Android:** fix `java.lang.NullPointerException` on `resumeAllGainedFocus`
+* [CB-12493](https://issues.apache.org/jira/browse/CB-12493) (Tests) Fixed spec.21 flakyness
+* major version bump, added `cordovaDependencies` requirement for `cordova-android>=6.1.0`
+* Add engine tag for checking `cordova-android`
+* Make the output file of **Android** an `acc` file.
+* [CB-12422](https://issues.apache.org/jira/browse/CB-12422) **iOS:** Fix readme issue on background needed plist modification
+* [CB-12434](https://issues.apache.org/jira/browse/CB-12434) **Android:** fix Stoping a Paused Recording throws exception
+* [CB-12411](https://issues.apache.org/jira/browse/CB-12411) Stoping a Paused Recording throws illegal state exception
+* [CB-1187](https://issues.apache.org/jira/browse/CB-1187) **iOS:** Fix unused recording settings
+* [CB-12353](https://issues.apache.org/jira/browse/CB-12353) Corrected merges usage in `plugin.xml`
+* [CB-12369](https://issues.apache.org/jira/browse/CB-12369) Add plugin typings from DefinitelyTyped
+* [CB-12363](https://issues.apache.org/jira/browse/CB-12363) Added build badges for **iOS 9.3** and **iOS 10.0**
+* [CB-12230](https://issues.apache.org/jira/browse/CB-12230) Removed **Windows 8.1** build badges
+
+### 2.4.1 (Dec 07, 2016)
+* [CB-12224](https://issues.apache.org/jira/browse/CB-12224) Updated version and RELEASENOTES.md for release 2.4.1
+* [CB-12034](https://issues.apache.org/jira/browse/CB-12034) (ios) Add mandatory iOS 10 privacy description
+* [CB-11917](https://issues.apache.org/jira/browse/CB-11917) - Remove pull request template checklist item: "iCLA has been submitted…"
+* [CB-11529](https://issues.apache.org/jira/browse/CB-11529) ios: Make available setting volume for player on ios device
+* [CB-11832](https://issues.apache.org/jira/browse/CB-11832) Incremented plugin version.
+
### 2.4.0 (Sep 08, 2016)
* [CB-11795](https://issues.apache.org/jira/browse/CB-11795) Add 'protective' entry to cordovaDependencies
* [CB-11793](https://issues.apache.org/jira/browse/CB-11793) fixed **android** build issue with last commit
diff --git a/doc/de/README.md b/doc/de/README.md
deleted file mode 100644
index 8fb1aba74..000000000
--- a/doc/de/README.md
+++ /dev/null
@@ -1,509 +0,0 @@
-
-
-# cordova-plugin-media
-
-[](https://travis-ci.org/apache/cordova-plugin-media)
-
-Dieses Plugin bietet die Möglichkeit zum Aufzeichnen und Wiedergeben von audio-Dateien auf einem Gerät.
-
-**Hinweis**: die aktuelle Implementierung eine W3C-Spezifikation für Medien-Capture nicht einhalten, und wird nur zu Informationszwecken zur Verfügung gestellt. Zukünftiger Implementierungen wird an der aktuellen W3C-Spezifikation und kann die aktuellen APIs entweiht.
-
-Dieses Plugin wird einen globalen `Media`-Konstruktor definiert.
-
-Obwohl im globalen Gültigkeitsbereich, steht es nicht bis nach dem `deviceready`-Ereignis.
-
- document.addEventListener("deviceready", onDeviceReady, false);
- function onDeviceReady() {
- console.log(Media);
- }
-
-
-## Installation
-
- cordova plugin add cordova-plugin-media
-
-
-## Unterstützte Plattformen
-
- * Android
- * BlackBerry 10
- * iOS
- * Windows Phone 7 und 8
- * Tizen
- * Windows 8
- * Windows
- * Browser
-
-## Windows Phone Macken
-
- * Nur eine Mediendatei kann gleichzeitig abgespielt werden.
-
- * Es gibt strenge Beschränkungen, wie Ihre Anwendung mit anderen Medien interagiert. Finden Sie in der [Microsoft-Dokumentation für details](http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx).
-
-## Medien
-
- var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### Parameter
-
- * **Src**: ein URI mit der audio-Inhalte. *(DOM-String und enthält)*
-
- * **MediaSuccess**: (Optional) der Rückruf, der nach dem führt ein `Media` -Objekt abgeschlossen hat, die aktuelle Wiedergabe, Aufzeichnung oder Stop-Action. *(Funktion)*
-
- * **Medienfehler**: (Optional) der Rückruf, der ausgeführt wird, wenn ein Fehler auftritt. *(Funktion)*
-
- * **MediaStatus**: (Optional) der Rückruf, der ausgeführt wird, um Statusänderungen anzugeben. *(Funktion)*
-
-### Konstanten
-
-Die folgenden Konstanten werden als einzigem Parameter an den `mediaStatus`-Rückruf gemeldet:
-
- * `Media.MEDIA_NONE`= 0;
- * `Media.MEDIA_STARTING`= 1;
- * `Media.MEDIA_RUNNING`= 2;
- * `Media.MEDIA_PAUSED`= 3;
- * `Media.MEDIA_STOPPED`= 4;
-
-### Methoden
-
- * `media.getCurrentPosition`: Gibt die aktuelle Position in einer Audiodatei.
-
- * `media.getDuration`: Gibt die Dauer einer Audiodatei.
-
- * `media.play`: Starten Sie oder fortsetzen Sie der Wiedergabe einer Audiodatei.
-
- * `media.pause`: Anhalten der Wiedergabe einer Audiodatei.
-
- * `media.release`: Das zugrunde liegende Betriebssystem audio Ressourcen frei.
-
- * `media.seekTo`: Verschiebt die Position innerhalb der audio-Datei.
-
- * `media.setVolume`: Stellen Sie die Lautstärke für die Audiowiedergabe.
-
- * `media.startRecord`: Starten der Aufnahme einer audio-Datei.
-
- * `media.stopRecord`: Stoppen Sie die Aufnahme einer audio-Datei.
-
- * `media.stop`: Abspielen einer Audiodatei zu stoppen.
-
-### Zusätzliche ReadOnly-Parameter
-
- * **Position**: die Position innerhalb der audio-Wiedergabe in Sekunden.
-
- * Nicht während des Spiels automatisch aktualisiert; Rufen Sie `getCurrentPosition` zu aktualisieren.
-
- * **Dauer**: die Dauer der Medien, in Sekunden.
-
-## media.getCurrentPosition
-
-Gibt die aktuelle Position in einer Audiodatei. Außerdem aktualisiert `das Medienobjekt` `position`-Parameter.
-
- media.getCurrentPosition(mediaSuccess, [mediaError]);
-
-
-### Parameter
-
- * **MediaSuccess**: der Rückruf, der die aktuelle Position in Sekunden übergeben wird.
-
- * **Medienfehler**: (Optional) der Rückruf ausgeführt, wenn ein Fehler auftritt.
-
-### Kurzes Beispiel
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Update media position every second
- var mediaTimer = setInterval(function () {
- // get media position
- my_media.getCurrentPosition(
- // success callback
- function (position) {
- if (position > -1) {
- console.log((position) + " sec");
- }
- },
- // error callback
- function (e) {
- console.log("Error getting pos=" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-Gibt die Dauer einer Audiodatei in Sekunden. Wenn die Dauer unbekannt ist, wird der Wert-1 zurückgegeben.
-
- media.getDuration();
-
-
-### Kurzes Beispiel
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(function() {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = my_media.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + " sec";
- }
- }, 100);
-
-
-## Media.Pause
-
-Pausen Abspielen einer Audiodatei.
-
- media.pause();
-
-
-### Kurzes Beispiel
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () { console.log("playAudio():Audio Success"); },
- // error callback
- function (err) { console.log("playAudio():Audio Error: " + err); }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function () {
- media.pause();
- }, 10000);
- }
-
-
-## Media.Play
-
-Startet oder setzt fort, Abspielen einer Audiodatei.
-
- media.play();
-
-
-### Kurzes Beispiel
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function (err) {
- console.log("playAudio():Audio Error: " + err);
- }
- );
- // Play audio
- my_media.play();
- }
-
-
-### iOS Macken
-
- * **NumberOfLoops**: übergeben Sie diese Option, um die `play` -Methode können Sie die Anzahl der angeben soll die Mediendatei ausspielen, z.B.:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
- * **PlayAudioWhenScreenIsLocked**: übergeben Sie diese Option, um die `play` -Methode können Sie angeben, ob Sie möchten Wiedergabe zu ermöglichen, wenn der Bildschirm gesperrt ist. Wenn legen Sie auf `true` (der Standardwert), der Zustand der die mute Taste wird ignoriert, z.B.:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
- * **Reihenfolge der Dateisuche**: Wenn nur ein Dateiname oder Pfad angegeben wird, sucht iOS in das `www` Verzeichnis für die Datei, dann in der Anwendung `documents/tmp` Verzeichnis:
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-Das zugrunde liegende Betriebssystem audio Ressourcen frei. Dies ist besonders wichtig für Android, da gibt es eine begrenzte Anzahl von OpenCore-Instanzen für die Medienwiedergabe. Anwendungen sollten die `release`-Funktion für alle `Media`-Ressourcen aufrufen, die nicht mehr benötigt wird.
-
- media.release();
-
-
-### Kurzes Beispiel
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- my_media.play();
- my_media.stop();
- my_media.release();
-
-
-## media.seekTo
-
-Legt die aktuelle Position in einer Audiodatei.
-
- media.seekTo(milliseconds);
-
-
-### Parameter
-
- * **miliseconds**: die Position die Wiedergabeposition innerhalb des Audiotracks in Millisekunden festgelegt.
-
-### Kurzes Beispiel
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
- my_media.play();
- // SeekTo to 10 seconds after 5 seconds
- setTimeout(function() {
- my_media.seekTo(10000);
- }, 5000);
-
-
-### BlackBerry 10 Macken
-
- * BlackBerry OS 5-Geräten unterstützt nicht.
-
-## media.setVolume
-
-Stellen Sie die Lautstärke für eine audio-Datei.
-
- media.setVolume(volume);
-
-
-### Parameter
-
- * **volume**: die Lautstärke für Wiedergabe fest. Der Wert muss im Bereich zwischen 0,0 und 1,0 liegen.
-
-### Unterstützte Plattformen
-
- * Android
- * iOS
-
-### Kurzes Beispiel
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- });
-
- // Play audio
- my_media.play();
-
- // Mute volume after 2 seconds
- setTimeout(function() {
- my_media.setVolume('0.0');
- }, 2000);
-
- // Set volume to 1.0 after 5 seconds
- setTimeout(function() {
- my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-Beginnt mit der Aufnahme einer audio-Datei.
-
- media.startRecord();
-
-
-### Unterstützte Plattformen
-
- * Android
- * iOS
- * Windows Phone 7 und 8
- * Windows
-
-### Kurzes Beispiel
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- });
-
- // Record audio
- mediaRec.startRecord();
- }
-
-
-### Android Eigenarten
-
- * Android-Geräte aufnehmen Audio im Adaptive Sprachcodecs Format. Die angegebene Datei sollte mit einer Endung *.amr* enden.
- * Die Hardware-Lautstärkeregler sind bis zu den Mediendatenträger angeschlossen, während alle Medienobjekte lebendig sind. Das letzte erstelltes Medium Objekt `release()` aufgerufen hat, werden einmal die Lautstärkeregler auf ihr Standardverhalten zurückgesetzt. Die Steuerelemente werden auch auf Seitennavigation, zurückgesetzt, wenn dies alle Medienobjekte freigibt.
-
-### iOS Macken
-
- * iOS nur Datensätze, die Dateien des Typs *WAV* und gibt ein Fehler, wenn die Dateinamen-Erweiterung ist richtig nicht.
-
- * Wenn ein vollständiger Pfad nicht angegeben ist, wird die Aufzeichnung in der Anwendung platziert `documents/tmp` Verzeichnis. Erreichbar über die `File` -API verwenden `LocalFileSystem.TEMPORARY` . Allen Unterverzeichnissen in Rekordzeit angegeben muss bereits vorhanden sein.
-
- * Dateien können aufgezeichnet und spielte mit die Dokumenten URI zurück:
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Windows-Eigenheiten
-
- * Windows-Geräte können MP3, M4A und WMA-Formate für die aufgezeichneten Audio. Jedoch ist in den meisten Fällen es nicht möglich, MP3 für audio-Aufnahme auf *Windows Phone 8.1* -Geräten verwenden, da ein MP3-Encoder [nicht mit Windows Phone geliefert ist](https://msdn.microsoft.com/en-us/library/windows/apps/windows.media.mediaproperties.mediaencodingprofile.createmp3.aspx).
-
- * Wenn Sie ein vollständiger Pfad nicht angegeben ist, wird die Aufnahme im AppData/Temp-Verzeichnis platziert. Erreichbar über die `Datei` API verwenden `LocalFileSystem.TEMPORARY` oder "ms-Appdata: / / / Temp /' URI.
-
- * Allen Unterverzeichnissen in Rekordzeit angegeben muss bereits vorhanden sein.
-
-### Tizen Macken
-
- * Tizen Geräten unterstützt nicht.
-
-## media.stop
-
-Beendet die Wiedergabe einer Audiodatei.
-
- media.stop();
-
-
-### Kurzes Beispiel
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function() {
- my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-Stoppt die Aufnahme einer audio-Datei.
-
- media.stopRecord();
-
-
-### Unterstützte Plattformen
-
- * Android
- * iOS
- * Windows Phone 7 und 8
- * Windows
-
-### Kurzes Beispiel
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- }
- );
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 seconds
- setTimeout(function() {
- mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### Tizen Macken
-
- * Tizen Geräten unterstützt nicht.
-
-## Medienfehler
-
-Ein `MediaError`-Objekt wird an die `mediaError`-Callback-Funktion zurückgegeben, wenn ein Fehler auftritt.
-
-### Eigenschaften
-
- * **Code**: einer der vordefinierten Fehlercodes aufgeführt.
-
- * **message**: eine Fehlermeldung beschreibt die Details des Fehlers.
-
-### Konstanten
-
- * `MediaError.MEDIA_ERR_ABORTED`= 1
- * `MediaError.MEDIA_ERR_NETWORK`= 2
- * `MediaError.MEDIA_ERR_DECODE`= 3
- * `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file
diff --git a/doc/de/index.md b/doc/de/index.md
deleted file mode 100644
index 68a1c7ae3..000000000
--- a/doc/de/index.md
+++ /dev/null
@@ -1,505 +0,0 @@
-
-
-# cordova-plugin-media
-
-Dieses Plugin bietet die Möglichkeit zum Aufzeichnen und Wiedergeben von audio-Dateien auf einem Gerät.
-
-**Hinweis**: die aktuelle Implementierung eine W3C-Spezifikation für Medien-Capture nicht einhalten, und wird nur zu Informationszwecken zur Verfügung gestellt. Zukünftiger Implementierungen wird an der aktuellen W3C-Spezifikation und kann die aktuellen APIs entweiht.
-
-Dieses Plugin wird einen globalen `Media`-Konstruktor definiert.
-
-Obwohl im globalen Gültigkeitsbereich, steht es nicht bis nach dem `deviceready`-Ereignis.
-
- document.addEventListener("deviceready", onDeviceReady, false);
- function onDeviceReady() {
- console.log(Media);
- }
-
-
-## Installation
-
- cordova plugin add cordova-plugin-media
-
-
-## Unterstützte Plattformen
-
-* Android
-* BlackBerry 10
-* iOS
-* Windows Phone 7 und 8
-* Tizen
-* Windows
-
-## Windows Phone Macken
-
-* Nur eine Mediendatei kann gleichzeitig abgespielt werden.
-
-* Es gibt strenge Beschränkungen, wie Ihre Anwendung mit anderen Medien interagiert. Finden Sie in der [Microsoft-Dokumentation für details][1].
-
- [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx
-
-## Medien
-
- var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### Parameter
-
-* **Src**: ein URI mit der audio-Inhalte. *(DOM-String und enthält)*
-
-* **MediaSuccess**: (Optional) der Rückruf, der nach dem führt ein `Media` -Objekt abgeschlossen hat, die aktuelle Wiedergabe, Aufzeichnung oder Stop-Action. *(Funktion)*
-
-* **Medienfehler**: (Optional) der Rückruf, der ausgeführt wird, wenn ein Fehler auftritt. *(Funktion)*
-
-* **MediaStatus**: (Optional) der Rückruf, der ausgeführt wird, um Statusänderungen anzugeben. *(Funktion)*
-
-### Konstanten
-
-Die folgenden Konstanten werden als einzigem Parameter an den `mediaStatus`-Rückruf gemeldet:
-
-* `Media.MEDIA_NONE`= 0;
-* `Media.MEDIA_STARTING`= 1;
-* `Media.MEDIA_RUNNING`= 2;
-* `Media.MEDIA_PAUSED`= 3;
-* `Media.MEDIA_STOPPED`= 4;
-
-### Methoden
-
-* `media.getCurrentPosition`: Gibt die aktuelle Position in einer Audiodatei.
-
-* `media.getDuration`: Gibt die Dauer einer Audiodatei.
-
-* `media.play`: Starten Sie oder fortsetzen Sie der Wiedergabe einer Audiodatei.
-
-* `media.pause`: Anhalten der Wiedergabe einer Audiodatei.
-
-* `media.release`: Das zugrunde liegende Betriebssystem audio Ressourcen frei.
-
-* `media.seekTo`: Verschiebt die Position innerhalb der audio-Datei.
-
-* `media.setVolume`: Stellen Sie die Lautstärke für die Audiowiedergabe.
-
-* `media.startRecord`: Starten der Aufnahme einer audio-Datei.
-
-* `media.stopRecord`: Stoppen Sie die Aufnahme einer audio-Datei.
-
-* `media.stop`: Abspielen einer Audiodatei zu stoppen.
-
-### Zusätzliche ReadOnly-Parameter
-
-* **Position**: die Position innerhalb der audio-Wiedergabe in Sekunden.
-
- * Nicht während des Spiels automatisch aktualisiert; Rufen Sie `getCurrentPosition` zu aktualisieren.
-
-* **Dauer**: die Dauer der Medien, in Sekunden.
-
-## media.getCurrentPosition
-
-Gibt die aktuelle Position in einer Audiodatei. Außerdem aktualisiert `das Medienobjekt` `position`-Parameter.
-
- media.getCurrentPosition(mediaSuccess, [mediaError]);
-
-
-### Parameter
-
-* **MediaSuccess**: der Rückruf, der die aktuelle Position in Sekunden übergeben wird.
-
-* **Medienfehler**: (Optional) der Rückruf ausgeführt, wenn ein Fehler auftritt.
-
-### Kurzes Beispiel
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Update media position every second
- var mediaTimer = setInterval(function () {
- // get media position
- my_media.getCurrentPosition(
- // success callback
- function (position) {
- if (position > -1) {
- console.log((position) + " sec");
- }
- },
- // error callback
- function (e) {
- console.log("Error getting pos=" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-Gibt die Dauer einer Audiodatei in Sekunden. Wenn die Dauer unbekannt ist, wird der Wert-1 zurückgegeben.
-
- media.getDuration();
-
-
-### Kurzes Beispiel
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(function() {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = my_media.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + " sec";
- }
- }, 100);
-
-
-## Media.Pause
-
-Pausen Abspielen einer Audiodatei.
-
- media.pause();
-
-
-### Kurzes Beispiel
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () { console.log("playAudio():Audio Success"); },
- // error callback
- function (err) { console.log("playAudio():Audio Error: " + err); }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function () {
- media.pause();
- }, 10000);
- }
-
-
-## Media.Play
-
-Startet oder setzt fort, Abspielen einer Audiodatei.
-
- media.play();
-
-
-### Kurzes Beispiel
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function (err) {
- console.log("playAudio():Audio Error: " + err);
- }
- );
- // Play audio
- my_media.play();
- }
-
-
-### iOS Macken
-
-* **NumberOfLoops**: übergeben Sie diese Option, um die `play` -Methode können Sie die Anzahl der angeben soll die Mediendatei ausspielen, z.B.:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
-* **PlayAudioWhenScreenIsLocked**: übergeben Sie diese Option, um die `play` -Methode können Sie angeben, ob Sie möchten Wiedergabe zu ermöglichen, wenn der Bildschirm gesperrt ist. Wenn legen Sie auf `true` (der Standardwert), der Zustand der die mute Taste wird ignoriert, z.B.:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
-* **Reihenfolge der Dateisuche**: Wenn nur ein Dateiname oder Pfad angegeben wird, sucht iOS in das `www` Verzeichnis für die Datei, dann in der Anwendung `documents/tmp` Verzeichnis:
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-Das zugrunde liegende Betriebssystem audio Ressourcen frei. Dies ist besonders wichtig für Android, da gibt es eine begrenzte Anzahl von OpenCore-Instanzen für die Medienwiedergabe. Anwendungen sollten die `release`-Funktion für alle `Media`-Ressourcen aufrufen, die nicht mehr benötigt wird.
-
- media.release();
-
-
-### Kurzes Beispiel
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- my_media.play();
- my_media.stop();
- my_media.release();
-
-
-## media.seekTo
-
-Legt die aktuelle Position in einer Audiodatei.
-
- media.seekTo(milliseconds);
-
-
-### Parameter
-
-* **miliseconds**: die Position die Wiedergabeposition innerhalb des Audiotracks in Millisekunden festgelegt.
-
-### Kurzes Beispiel
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
- my_media.play();
- // SeekTo to 10 seconds after 5 seconds
- setTimeout(function() {
- my_media.seekTo(10000);
- }, 5000);
-
-
-### BlackBerry 10 Macken
-
-* BlackBerry OS 5-Geräten unterstützt nicht.
-
-## media.setVolume
-
-Stellen Sie die Lautstärke für eine audio-Datei.
-
- media.setVolume(volume);
-
-
-### Parameter
-
-* **volume**: die Lautstärke für Wiedergabe fest. Der Wert muss im Bereich zwischen 0,0 und 1,0 liegen.
-
-### Unterstützte Plattformen
-
-* Android
-* iOS
-
-### Kurzes Beispiel
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- });
-
- // Play audio
- my_media.play();
-
- // Mute volume after 2 seconds
- setTimeout(function() {
- my_media.setVolume('0.0');
- }, 2000);
-
- // Set volume to 1.0 after 5 seconds
- setTimeout(function() {
- my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-Beginnt mit der Aufnahme einer audio-Datei.
-
- media.startRecord();
-
-
-### Unterstützte Plattformen
-
-* Android
-* iOS
-* Windows Phone 7 und 8
-* Windows
-
-### Kurzes Beispiel
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- });
-
- // Record audio
- mediaRec.startRecord();
- }
-
-
-### Android Eigenarten
-
-* Android-Geräte aufnehmen Audio im Adaptive Sprachcodecs Format. Die angegebene Datei sollte mit einer Endung *.amr* enden.
-* Die Hardware-Lautstärkeregler sind bis zu den Mediendatenträger angeschlossen, während alle Medienobjekte lebendig sind. Das letzte erstelltes Medium Objekt `release()` aufgerufen hat, werden einmal die Lautstärkeregler auf ihr Standardverhalten zurückgesetzt. Die Steuerelemente werden auch auf Seitennavigation, zurückgesetzt, wenn dies alle Medienobjekte freigibt.
-
-### iOS Macken
-
-* iOS nur Datensätze, die Dateien des Typs *WAV* und gibt ein Fehler, wenn die Dateinamen-Erweiterung ist richtig nicht.
-
-* Wenn ein vollständiger Pfad nicht angegeben ist, wird die Aufzeichnung in der Anwendung platziert `documents/tmp` Verzeichnis. Erreichbar über die `File` -API verwenden `LocalFileSystem.TEMPORARY` . Allen Unterverzeichnissen in Rekordzeit angegeben muss bereits vorhanden sein.
-
-* Dateien können aufgezeichnet und spielte mit die Dokumenten URI zurück:
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Windows-Eigenheiten
-
-* Wenn Sie ein vollständiger Pfad nicht angegeben ist, wird die Aufnahme im AppData/Temp-Verzeichnis platziert. Erreichbar über die `Datei` API verwenden `LocalFileSystem.TEMPORARY` oder "ms-Appdata: / / / Temp /' URI.
-
-* Allen Unterverzeichnissen in Rekordzeit angegeben muss bereits vorhanden sein.
-
-### Tizen Macken
-
-* Tizen Geräten unterstützt nicht.
-
-## media.stop
-
-Beendet die Wiedergabe einer Audiodatei.
-
- media.stop();
-
-
-### Kurzes Beispiel
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function() {
- my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-Stoppt die Aufnahme einer audio-Datei.
-
- media.stopRecord();
-
-
-### Unterstützte Plattformen
-
-* Android
-* iOS
-* Windows Phone 7 und 8
-* Windows
-
-### Kurzes Beispiel
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- }
- );
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 seconds
- setTimeout(function() {
- mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### Tizen Macken
-
-* Tizen Geräten unterstützt nicht.
-
-## Medienfehler
-
-Ein `MediaError`-Objekt wird an die `mediaError`-Callback-Funktion zurückgegeben, wenn ein Fehler auftritt.
-
-### Eigenschaften
-
-* **Code**: einer der vordefinierten Fehlercodes aufgeführt.
-
-* **message**: eine Fehlermeldung beschreibt die Details des Fehlers.
-
-### Konstanten
-
-* `MediaError.MEDIA_ERR_ABORTED`= 1
-* `MediaError.MEDIA_ERR_NETWORK`= 2
-* `MediaError.MEDIA_ERR_DECODE`= 3
-* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
diff --git a/doc/es/README.md b/doc/es/README.md
deleted file mode 100644
index 78ce57051..000000000
--- a/doc/es/README.md
+++ /dev/null
@@ -1,509 +0,0 @@
-
-
-# cordova-plugin-media
-
-[](https://travis-ci.org/apache/cordova-plugin-media)
-
-Este plugin proporciona la capacidad de grabar y reproducir archivos de audio en un dispositivo.
-
-**Nota**: la implementación actual no se adhiere a una especificación del W3C para la captura de los medios de comunicación y se proporciona únicamente para su comodidad. Una futura implementación se adherirá a la más reciente especificación W3C y puede desaprueban las API actuales.
-
-Este plugin define un global `Media` Constructor.
-
-Aunque en el ámbito global, no estará disponible hasta después de la `deviceready` evento.
-
- document.addEventListener("deviceready", onDeviceReady, false);
- function onDeviceReady() {
- console.log(Media);
- }
-
-
-## Instalación
-
- cordova plugin add cordova-plugin-media
-
-
-## Plataformas soportadas
-
- * Android
- * BlackBerry 10
- * iOS
- * Windows Phone 7 y 8
- * Tizen
- * Windows 8
- * Windows
- * Explorador
-
-## Windows Phone rarezas
-
- * Archivo único multimedia puede reproducir en un momento.
-
- * Hay restricciones estrictas sobre cómo interactúa la aplicación con otros medios. Consulte la [documentación de Microsoft para obtener más detalles](http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx).
-
-## Los medios de comunicación
-
- var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### Parámetros
-
- * **src**: un URI que contiene el contenido de audio. *(DOMString)*
-
- * **mediaSuccess**: (opcional) la devolución de llamada que se ejecuta después de que un objeto `Media` ha completado el juego actual, registro o acción. *(Function)*
-
- * **mediaError**: (opcional) la devolución de llamada que se ejecuta si se produce un error. *(Función)*
-
- * **mediaStatus**: (opcional) la devolución de llamada que se ejecuta para indicar cambios en el estado. *(Función)*
-
-### Constantes
-
-Las siguientes constantes son reportadas como el único parámetro a la `mediaStatus` callback:
-
- * `Media.MEDIA_NONE` = 0;
- * `Media.MEDIA_STARTING` = 1;
- * `Media.MEDIA_RUNNING` = 2;
- * `Media.MEDIA_PAUSED` = 3;
- * `Media.MEDIA_STOPPED` = 4;
-
-### Métodos
-
- * `media.getCurrentPosition`: devuelve la posición actual dentro de un archivo de audio.
-
- * `media.getDuration`: devuelve la duración de un archivo de audio.
-
- * `media.play`: iniciar o reanudar reproducción de un archivo de audio.
-
- * `media.pause`: pausar la reproducción de un archivo de audio.
-
- * `media.release`: libera recursos de audio del sistema operativo subyacente.
-
- * `media.seekTo`: mueve la posición dentro del archivo de audio.
-
- * `media.setVolume`: ajuste el volumen de reproducción de audio.
-
- * `media.startRecord`: iniciar la grabación de un archivo de audio.
-
- * `media.stopRecord`: dejar de grabar un archivo de audio.
-
- * `media.stop`: deja de jugar a un archivo de audio.
-
-### Parámetros adicionales ReadOnly
-
- * **posición**: la posición dentro de la reproducción de audio, en segundos.
-
- * No actualizada automáticamente durante la reproducción; Llame a `getCurrentPosition` para actualizar.
-
- * **duration**: la duración de los medios de comunicación, en segundos.
-
-## media.getCurrentPosition
-
-Devuelve la posición actual dentro de un archivo de audio. También actualiza el `Media` del objeto `position` parámetro.
-
- media.getCurrentPosition(mediaSuccess, [mediaError]);
-
-
-### Parámetros
-
- * **mediaSuccess**: la devolución de llamada que se pasa a la posición actual en segundos.
-
- * **mediaError**: (opcional) la devolución de llamada para ejecutar si se produce un error.
-
-### Ejemplo rápido
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Update media position every second
- var mediaTimer = setInterval(function () {
- // get media position
- my_media.getCurrentPosition(
- // success callback
- function (position) {
- if (position > -1) {
- console.log((position) + " sec");
- }
- },
- // error callback
- function (e) {
- console.log("Error getting pos=" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-Devuelve la duración de un archivo de audio en segundos. Si se desconoce la duración, devuelve un valor de -1.
-
- media.getDuration();
-
-
-### Ejemplo rápido
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(function() {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = my_media.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + " sec";
- }
- }, 100);
-
-
-## media.pause
-
-Detiene temporalmente la reproducción de un archivo de audio.
-
- media.pause();
-
-
-### Ejemplo rápido
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () { console.log("playAudio():Audio Success"); },
- // error callback
- function (err) { console.log("playAudio():Audio Error: " + err); }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function () {
- media.pause();
- }, 10000);
- }
-
-
-## media.play
-
-Inicia o reanuda la reproducción de un archivo de audio.
-
- media.play();
-
-
-### Ejemplo rápido
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function (err) {
- console.log("playAudio():Audio Error: " + err);
- }
- );
- // Play audio
- my_media.play();
- }
-
-
-### iOS rarezas
-
- * **numberOfLoops**: pasar esta opción al método `play` para especificar el número de veces que desea que los medios de archivo para jugar, por ejemplo:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
- * **playAudioWhenScreenIsLocked**: pasar en esta opción el método `play` para especificar si desea permitir la reproducción cuando la pantalla está bloqueada. Si se omite establecido en `true` (el valor predeterminado), el estado del botón mute hardware, por ejemplo:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
- * **orden de búsqueda de archivos**: cuando se proporciona sólo un nombre de archivo o ruta simple, iOS busca en el directorio `www` para el archivo, luego en el directorio de la aplicación `documents/tmp`:
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-Libera los recursos de audio del sistema operativo subyacente. Esto es particularmente importante para Android, ya que hay una cantidad finita de instancias de OpenCore para la reproducción multimedia. Las aplicaciones deben llamar el `release` función para cualquier `Media` recurso que ya no es necesario.
-
- media.release();
-
-
-### Ejemplo rápido
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- my_media.play();
- my_media.stop();
- my_media.release();
-
-
-## media.seekTo
-
-Establece la posición actual dentro de un archivo de audio.
-
- media.seekTo(milliseconds);
-
-
-### Parámetros
-
- * **milliseconds**: la posición para ajustar la posición de reproducción en el audio, en milisegundos.
-
-### Ejemplo rápido
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
- my_media.play();
- // SeekTo to 10 seconds after 5 seconds
- setTimeout(function() {
- my_media.seekTo(10000);
- }, 5000);
-
-
-### BlackBerry 10 rarezas
-
- * No compatible con dispositivos BlackBerry OS 5.
-
-## media.setVolume
-
-Ajuste el volumen para un archivo de audio.
-
- media.setVolume(volume);
-
-
-### Parámetros
-
- * **volume**: el volumen para la reproducción. El valor debe estar dentro del rango de 0.0 a 1.0.
-
-### Plataformas soportadas
-
- * Android
- * iOS
-
-### Ejemplo rápido
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- });
-
- // Play audio
- my_media.play();
-
- // Mute volume after 2 seconds
- setTimeout(function() {
- my_media.setVolume('0.0');
- }, 2000);
-
- // Set volume to 1.0 after 5 seconds
- setTimeout(function() {
- my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-Empieza a grabar un archivo de audio.
-
- media.startRecord();
-
-
-### Plataformas soportadas
-
- * Android
- * iOS
- * Windows Phone 7 y 8
- * Windows
-
-### Ejemplo rápido
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- });
-
- // Record audio
- mediaRec.startRecord();
- }
-
-
-### Rarezas Android
-
- * Dispositivos Android grabación audio en formato Adaptive Multi-rate. El archivo especificado debe terminar con una extensión de *.amr*.
- * Los controles de volumen del hardware están conectados hasta el volumen de los medios de comunicación, mientras que los objetos a los medios de comunicación están vivos. Una vez creado el último objeto multimedia ha `release()` llamado en él, los controles de volumen volverá a su comportamiento por defecto. Los controles también se restablecen en la navegación de la página, como esto libera todos los objetos de los medios de comunicación.
-
-### iOS rarezas
-
- * iOS únicos registros a archivos de tipo *.wav* y devuelve un error si el archivo de extensión el nombre es no es correcto.
-
- * Si no se proporciona una ruta completa, la grabación se coloca en el directorio de la aplicación `documents/tmp`. Esto se puede acceder mediante el `File` API utilizando `LocalFileSystem.TEMPORARY`. Ya debe existir cualquier subdirectorio especificado en un tiempo récord.
-
- * Archivos pueden ser grabados y jugó de nuevo usando los documentos URI:
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Windows rarezas
-
- * Dispositivos Windows pueden usar MP3, M4A y WMA formatos de grabado de audio. Sin embargo en la mayoría de los casos no es posible utilizar MP3 para grabar audio en los dispositivos *Windows Phone 8.1* , debido a que un codificador de MP3 es [no enviado con Windows Phone](https://msdn.microsoft.com/en-us/library/windows/apps/windows.media.mediaproperties.mediaencodingprofile.createmp3.aspx).
-
- * Si no se proporciona una ruta completa, la grabación se coloca en el directorio AppData/temp. Esto puede accederse a través de la `Archivo` Usando API `LocalFileSystem.TEMPORARY` o ' ms-appdata: temporal / / / /' URI.
-
- * Ya debe existir cualquier subdirectorio especificado en un tiempo récord.
-
-### Rarezas Tizen
-
- * No compatible con dispositivos Tizen.
-
-## media.stop
-
-Deja de reproducir un archivo de audio.
-
- media.stop();
-
-
-### Ejemplo rápido
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function() {
- my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-Detiene la grabación de un archivo de audio.
-
- media.stopRecord();
-
-
-### Plataformas soportadas
-
- * Android
- * iOS
- * Windows Phone 7 y 8
- * Windows
-
-### Ejemplo rápido
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- }
- );
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 seconds
- setTimeout(function() {
- mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### Rarezas Tizen
-
- * No compatible con dispositivos Tizen.
-
-## MediaError
-
-A `MediaError` objeto es devuelto a la `mediaError` función de devolución de llamada cuando se produce un error.
-
-### Propiedades
-
- * **code**: uno de los códigos de error predefinido enumerados a continuación.
-
- * **mensaje**: un mensaje de error que describe los detalles del error.
-
-### Constantes
-
- * `MediaError.MEDIA_ERR_ABORTED` = 1
- * `MediaError.MEDIA_ERR_NETWORK` = 2
- * `MediaError.MEDIA_ERR_DECODE` = 3
- * `MediaError.MEDIA_ERR_NONE_SUPPORTED` = 4
\ No newline at end of file
diff --git a/doc/es/index.md b/doc/es/index.md
deleted file mode 100644
index d910b016e..000000000
--- a/doc/es/index.md
+++ /dev/null
@@ -1,400 +0,0 @@
-
-
-# cordova-plugin-media
-
-Este plugin proporciona la capacidad de grabar y reproducir archivos de audio en un dispositivo.
-
-**Nota**: la implementación actual no se adhiere a una especificación del W3C para la captura de los medios de comunicación y se proporciona únicamente para su comodidad. Una futura implementación se adherirá a la más reciente especificación W3C y puede desaprueban las API actuales.
-
-Este plugin define un global `Media` Constructor.
-
-Aunque en el ámbito global, no estará disponible hasta después de la `deviceready` evento.
-
- document.addEventListener ("deviceready", onDeviceReady, false);
- function onDeviceReady() {console.log(Media)};
-
-
-## Instalación
-
- Cordova plugin agregar cordova-plugin-media
-
-
-## Plataformas soportadas
-
-* Android
-* BlackBerry 10
-* iOS
-* Windows Phone 7 y 8
-* Tizen
-* Windows
-
-## Windows Phone rarezas
-
-* Archivo único multimedia puede reproducir en un momento.
-
-* Hay restricciones estrictas sobre cómo interactúa la aplicación con otros medios. Consulte la [documentación de Microsoft para obtener más detalles][1].
-
- [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx
-
-## Los medios de comunicación
-
- los medios de comunicación var = new Media (src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### Parámetros
-
-* **src**: un URI que contiene el contenido de audio. *(DOMString)*
-
-* **mediaSuccess**: (opcional) la devolución de llamada que se ejecuta después de que un objeto `Media` ha completado el juego actual, registro o acción. *(Function)*
-
-* **mediaError**: (opcional) la devolución de llamada que se ejecuta si se produce un error. *(Función)*
-
-* **mediaStatus**: (opcional) la devolución de llamada que se ejecuta para indicar cambios en el estado. *(Función)*
-
-### Constantes
-
-Las siguientes constantes son reportadas como el único parámetro a la `mediaStatus` callback:
-
-* `Media.MEDIA_NONE` = 0;
-* `Media.MEDIA_STARTING` = 1;
-* `Media.MEDIA_RUNNING` = 2;
-* `Media.MEDIA_PAUSED` = 3;
-* `Media.MEDIA_STOPPED` = 4;
-
-### Métodos
-
-* `media.getCurrentPosition`: devuelve la posición actual dentro de un archivo de audio.
-
-* `media.getDuration`: devuelve la duración de un archivo de audio.
-
-* `media.play`: iniciar o reanudar reproducción de un archivo de audio.
-
-* `media.pause`: pausar la reproducción de un archivo de audio.
-
-* `media.release`: libera recursos de audio del sistema operativo subyacente.
-
-* `media.seekTo`: mueve la posición dentro del archivo de audio.
-
-* `media.setVolume`: ajuste el volumen de reproducción de audio.
-
-* `media.startRecord`: iniciar la grabación de un archivo de audio.
-
-* `media.stopRecord`: dejar de grabar un archivo de audio.
-
-* `media.stop`: deja de jugar a un archivo de audio.
-
-### Parámetros adicionales ReadOnly
-
-* **posición**: la posición dentro de la reproducción de audio, en segundos.
-
- * No actualizada automáticamente durante la reproducción; Llame a `getCurrentPosition` para actualizar.
-
-* **duration**: la duración de los medios de comunicación, en segundos.
-
-## media.getCurrentPosition
-
-Devuelve la posición actual dentro de un archivo de audio. También actualiza el `Media` del objeto `position` parámetro.
-
- media.getCurrentPosition (mediaSuccess, [mediaError]);
-
-
-### Parámetros
-
-* **mediaSuccess**: la devolución de llamada que se pasa a la posición actual en segundos.
-
-* **mediaError**: (opcional) la devolución de llamada para ejecutar si se produce un error.
-
-### Ejemplo rápido
-
- Reproductor de audio / / var my_media = new Media (src, onSuccess, onError);
-
- Actualización medios posición cada segundo var mediaTimer = setInterval(function () {/ / obtener medios posición my_media.getCurrentPosition (/ / función de devolución de llamada de éxito (posición) {si (posición > -1) {console.log((position) + "sec");
- }}, / / función de callback de error (e) {console.log ("Error al obtener pos =" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-Devuelve la duración de un archivo de audio en segundos. Si se desconoce la duración, devuelve un valor de -1.
-
- media.getDuration();
-
-
-### Ejemplo rápido
-
- Reproductor de audio / / var my_media = new Media (src, onSuccess, onError);
-
- Obtener contador duración var = 0;
- var timerDur = setInterval(function() {contador = contador + 100;
- Si (contador > 2000) {clearInterval(timerDur);
- } var dur = my_media.getDuration();
- Si (dur > 0) {clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + "sec";
- }}, 100);
-
-
-## media.pause
-
-Detiene temporalmente la reproducción de un archivo de audio.
-
- media.Pause();
-
-
-### Ejemplo rápido
-
- Reproducir audio / / function playAudio(url) {/ / reproducción del archivo de audio en my_media var url = new Media (url, / / función de devolución de llamada de éxito () {console.log ("(playAudio): Audio éxito");}, / / función de callback de error (err) {console.log ("(playAudio): Audio Error:" + err);});
-
- Reproducir audio my_media.play();
-
- Hacer una pausa después de 10 segundos setTimeout (function () {media.pause();
- }, 10000);
- }
-
-
-## media.play
-
-Inicia o reanuda la reproducción de un archivo de audio.
-
- media.Play();
-
-
-### Ejemplo rápido
-
- Reproducir audio / / function playAudio(url) {/ / reproducción del archivo de audio en el url var my_media = new Media (url, / / función de devolución de llamada de éxito () {console.log ("(playAudio): Audio éxito");
- }, / / función de callback de error (err) {console.log ("(playAudio): Audio Error:" + err);
- }
- );
- Reproducir audio my_media.play();
- }
-
-
-### iOS rarezas
-
-* **numberOfLoops**: pasar esta opción al método `play` para especificar el número de veces que desea que los medios de archivo para jugar, por ejemplo:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
-* **playAudioWhenScreenIsLocked**: pasar en esta opción el método `play` para especificar si desea permitir la reproducción cuando la pantalla está bloqueada. Si se omite establecido en `true` (el valor predeterminado), el estado del botón mute hardware, por ejemplo:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
-* **orden de búsqueda de archivos**: cuando se proporciona sólo un nombre de archivo o ruta simple, iOS busca en el directorio `www` para el archivo, luego en el directorio de la aplicación `documents/tmp`:
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-Libera los recursos de audio del sistema operativo subyacente. Esto es particularmente importante para Android, ya que hay una cantidad finita de instancias de OpenCore para la reproducción multimedia. Las aplicaciones deben llamar el `release` función para cualquier `Media` recurso que ya no es necesario.
-
- media.Release();
-
-
-### Ejemplo rápido
-
- Reproductor de audio / / var my_media = new Media (src, onSuccess, onError);
-
- my_media.Play();
- my_media.STOP();
- my_media.Release();
-
-
-## media.seekTo
-
-Establece la posición actual dentro de un archivo de audio.
-
- media.seekTo(milliseconds);
-
-
-### Parámetros
-
-* **milliseconds**: la posición para ajustar la posición de reproducción en el audio, en milisegundos.
-
-### Ejemplo rápido
-
- Reproductor de audio / / var my_media = new Media (src, onSuccess, onError);
- my_media.Play();
- Buscan a 10 segundos después de 5 segundos setTimeout(function() {my_media.seekTo(10000);}, 5000);
-
-
-### BlackBerry 10 rarezas
-
-* No compatible con dispositivos BlackBerry OS 5.
-
-## media.setVolume
-
-Ajuste el volumen para un archivo de audio.
-
- media.setVolume(volume);
-
-
-### Parámetros
-
-* **volume**: el volumen para la reproducción. El valor debe estar dentro del rango de 0.0 a 1.0.
-
-### Plataformas soportadas
-
-* Android
-* iOS
-
-### Ejemplo rápido
-
- Reproducir audio / / function playAudio(url) {/ / reproducción del archivo de audio en el url var my_media = new Media (url, / / éxito callback function() {console.log ("(playAudio): Audio éxito");
- }, / / error callback function(err) {console.log ("(playAudio): Audio Error:" + err);
- });
-
- Reproducir audio my_media.play();
-
- Silenciar el volumen después de 2 segundos setTimeout(function() {my_media.setVolume('0.0');
- }, 2000);
-
- Ajustar volumen 1.0 después de 5 segundos setTimeout(function() {my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-Empieza a grabar un archivo de audio.
-
- media.startRecord();
-
-
-### Plataformas soportadas
-
-* Android
-* iOS
-* Windows Phone 7 y 8
-* Windows
-
-### Ejemplo rápido
-
- Grabar audio / / function recordAudio() {var src = "myrecording.mp3";
- var mediaRec = new Media (src, / / éxito callback function() {console.log ("(recordAudio): Audio éxito");
- }, / / error callback function(err) {console.log ("(recordAudio): Audio Error:" + err.code);
- });
-
- Grabar audio mediaRec.startRecord();
- }
-
-
-### Rarezas Android
-
-* Dispositivos Android grabación audio en formato Adaptive Multi-rate. El archivo especificado debe terminar con una extensión de *.amr*.
-* Los controles de volumen del hardware están conectados hasta el volumen de los medios de comunicación, mientras que los objetos a los medios de comunicación están vivos. Una vez creado el último objeto multimedia ha `release()` llamado en él, los controles de volumen volverá a su comportamiento por defecto. Los controles también se restablecen en la navegación de la página, como esto libera todos los objetos de los medios de comunicación.
-
-### iOS rarezas
-
-* iOS únicos registros a archivos de tipo *.wav* y devuelve un error si el archivo de extensión el nombre es no es correcto.
-
-* Si no se proporciona una ruta completa, la grabación se coloca en el directorio de la aplicación `documents/tmp`. Esto se puede acceder mediante el `File` API utilizando `LocalFileSystem.TEMPORARY`. Ya debe existir cualquier subdirectorio especificado en un tiempo récord.
-
-* Archivos pueden ser grabados y jugó de nuevo usando los documentos URI:
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Windows rarezas
-
-* Si no se proporciona una ruta completa, la grabación se coloca en el directorio AppData/temp. Esto puede accederse a través de la `Archivo` Usando API `LocalFileSystem.TEMPORARY` o ' ms-appdata: temporal / / / /' URI.
-
-* Ya debe existir cualquier subdirectorio especificado en un tiempo récord.
-
-### Rarezas Tizen
-
-* No compatible con dispositivos Tizen.
-
-## media.stop
-
-Deja de reproducir un archivo de audio.
-
- media.STOP();
-
-
-### Ejemplo rápido
-
- Reproducir audio / / function playAudio(url) {/ / reproducción del archivo de audio en el url var my_media = new Media (url, / / éxito callback function() {console.log ("(playAudio): Audio éxito");
- }, / / error callback function(err) {console.log ("(playAudio): Audio Error:" + err);
- }
- );
-
- Reproducir audio my_media.play();
-
- Hacer una pausa después de 10 segundos setTimeout(function() {my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-Detiene la grabación de un archivo de audio.
-
- media.stopRecord();
-
-
-### Plataformas soportadas
-
-* Android
-* iOS
-* Windows Phone 7 y 8
-* Windows
-
-### Ejemplo rápido
-
- Grabar audio / / function recordAudio() {var src = "myrecording.mp3";
- var mediaRec = new Media (src, / / éxito callback function() {console.log ("(recordAudio): Audio éxito");
- }, / / error callback function(err) {console.log ("(recordAudio): Audio Error:" + err.code);
- }
- );
-
- Grabar audio mediaRec.startRecord();
-
- Detener la grabación después de 10 segundos setTimeout(function() {mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### Rarezas Tizen
-
-* No compatible con dispositivos Tizen.
-
-## MediaError
-
-A `MediaError` objeto es devuelto a la `mediaError` función de devolución de llamada cuando se produce un error.
-
-### Propiedades
-
-* **code**: uno de los códigos de error predefinido enumerados a continuación.
-
-* **mensaje**: un mensaje de error que describe los detalles del error.
-
-### Constantes
-
-* `MediaError.MEDIA_ERR_ABORTED`= 1
-* `MediaError.MEDIA_ERR_NETWORK`= 2
-* `MediaError.MEDIA_ERR_DECODE`= 3
-* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
diff --git a/doc/fr/README.md b/doc/fr/README.md
deleted file mode 100644
index db3d3d17e..000000000
--- a/doc/fr/README.md
+++ /dev/null
@@ -1,404 +0,0 @@
-
-
-# cordova-plugin-media
-
-[](https://travis-ci.org/apache/cordova-plugin-media)
-
-Ce plugin permet d'enregistrer et de lire des fichiers audio sur un périphérique.
-
-**Remarque**: l'implémentation actuelle n'est pas conforme à une spécification du W3C pour la capture de médias et est fournie pour plus de commodité seulement. Une prochaine implémentation adhèrera à la toute dernière spécification du W3C, ce qui aura probablement pour effet de déprécier l'API actuelle.
-
-Ce plugin définit un global `Media` constructeur.
-
-Bien que dans la portée globale, il n'est pas disponible jusqu'après la `deviceready` événement.
-
- document.addEventListener (« deviceready », onDeviceReady, false) ;
- function onDeviceReady() {console.log(Media);}
-
-
-## Installation
-
- cordova plugin add cordova-plugin-media
-
-
-## Plates-formes supportées
-
- * Android
- * BlackBerry 10
- * iOS
- * Windows Phone 7 et 8
- * Paciarelli
- * Windows 8
- * Windows
- * Navigateur
-
-## Windows Phone Quirks
-
- * Un seul fichier média peut être lu à la fois.
-
- * Il y a des restrictions strictes concernant la façon dont votre application interagit avec d'autres médias. Consultez la [documentation de Microsoft pour plus d'informations](http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx).
-
-## Media
-
- médias var = new Media (src, mediaSuccess, [mediaError], [mediaStatus]) ;
-
-
-### Paramètres
-
- * **src** : l'URI du contenu audio. *(DOMString)*
-
- * **mediaSuccess** : (facultative) la fonction callback exécutée après que la lecture en cours, l'action d'enregistrement ou l'arrêt de lecture de l'objet `Media` soit terminée. *(Function)*
-
- * **mediaError** : (facultative) la fonction callback exécutée si une erreur survient. *(Function)*
-
- * **mediaStatus** : (facultative) la fonction callback exécutée lors de chaque changement d'état. *(Function)*
-
-### Constantes
-
-Les constantes suivantes sont déclarées comme le seul paramètre à la `mediaStatus` Rappel :
-
- * `Media.MEDIA_NONE` = 0;
- * `Media.MEDIA_STARTING` = 1;
- * `Media.MEDIA_RUNNING` = 2;
- * `Media.MEDIA_PAUSED` = 3;
- * `Media.MEDIA_STOPPED` = 4;
-
-### Méthodes
-
- * `media.getCurrentPosition` : retourne la position de lecture dans un fichier audio.
-
- * `media.getDuration`: retourne la durée d'un fichier audio.
-
- * `media.play` : permet de commencer ou reprendre la lecture d'un fichier audio.
-
- * `media.pause` : interrompt la lecture d'un fichier audio.
-
- * `media.release` : libère les ressources audio correspondantes du système d'exploitation.
-
- * `media.seekTo` : déplace la position de lecture au sein du fichier audio.
-
- * `media.setVolume` : permet de régler le volume du clip audio.
-
- * `media.startRecord` : commence l'enregistrement d'un fichier audio.
-
- * `media.stopRecord` : arrête l'enregistrement d'un fichier audio.
-
- * `media.stop` : arrête la lecture d'un fichier audio.
-
-### Paramètres supplémentaires en lecture seule
-
- * **position** : la position de lecture sein du clip audio, en secondes.
-
- * La valeur n'est pas automatiquement rafraichie pendant la lecture ; un appel à `getCurrentPosition` permet sa mise à jour.
-
- * **duration** : la durée du média, en secondes.
-
-## media.getCurrentPosition
-
-Retourne la position courante dans un fichier audio. Met également à jour la `Media` de l'objet `position` paramètre.
-
- media.getCurrentPosition (mediaSuccess, [mediaError]) ;
-
-
-### Paramètres
-
- * **mediaSuccess** : la fonction callback à laquelle est transmise la position actuelle exprimée en secondes.
-
- * **mediaError** : (facultative) la fonction callback exécutée si une erreur se produit.
-
-### Exemple court
-
- Lecteur audio / / var my_media = new Media (src, onSuccess, onError) ;
-
- Mise à jour media positionner chaque deuxième mediaTimer de var = setInterval(function () {/ / get médias position my_media.getCurrentPosition (/ / fonction de rappel réussi (position) {si (position > -1) {console.log((position) + "secondes") ;
- }}, / / fonction de rappel d'erreur (e) {console.log ("Error getting pos =" + e) ;
- }
- );
- }, 1000) ;
-
-
-## media.getDuration
-
-Retourne la durée d'un fichier audio en quelques secondes. Si on ne connaît pas la durée, elle retourne la valeur -1.
-
- media.getDuration() ;
-
-
-### Exemple court
-
- Lecteur audio / / var my_media = new Media (src, onSuccess, onError) ;
-
- Obtenez durée var compteur = 0 ;
- var timerDur = setInterval(function() {Compteur = compteur + 100 ;
- Si (contrer > 2000) {clearInterval(timerDur) ;
- } var dur = my_media.getDuration() ;
- Si (dur > 0) {clearInterval(timerDur) ;
- document.getElementById('audio_duration').innerHTML = (dur) + "secondes" ;
- }}, 100) ;
-
-
-## media.pause
-
-Suspendre la lecture d'un fichier audio.
-
- Media.pause() ;
-
-
-### Exemple court
-
- Lire les données audio / / function playAudio(url) {/ / lire le fichier audio à my_media var url = nouveaux médias (url, / / fonction de rappel réussi () {console.log ("playAudio (): Audio succès");}, / / fonction de rappel d'erreur (err) {console.log ("playAudio (): erreur Audio:" + err);}) ;
-
- Lecture audio my_media.play() ;
-
- Pause après 10 secondes setTimeout (function () {media.pause() ;
- }, 10000) ;
- }
-
-
-## media.play
-
-Commence ou reprend la lecture d'un fichier audio.
-
- Media.Play() ;
-
-
-### Exemple court
-
- Lire les données audio / / function playAudio(url) {/ / lire le fichier audio à url var my_media = new Media (url, / / fonction de rappel réussi () {console.log ("playAudio (): Audio succès") ;
- }, / / fonction de rappel d'erreur (err) {console.log ("playAudio (): Audio Error:" + err) ;
- }
- );
- Lecture audio my_media.play() ;
- }
-
-
-### Notes au sujet d'iOS
-
- * **numberOfLoops** : transmettre cette option à la méthode `play` permet de spécifier le nombre de lectures à la suite d'un fichier donné, par exemple :
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
- * **playAudioWhenScreenIsLocked** : transmettre cette option à la méthode `play` permet de spécifier si la lecture doit continuer même lorsque l'écran de l'appareil est verrouillé. Si la valeur est `true` (par défaut), le bouton matériel mute est ignoré, par exemple :
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
- * **ordre de recherche de fichier** : si un nom de fichier ou chemin d'accès simple est fourni, iOS recherche d'abord le fichier correspondant dans le répertoire `www`, puis dans le répertoire `documents/tmp` appartenant à l'application :
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // recherche d'abord le fichier www/audio/beer.mp3 puis /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-Libère les ressources audio du système d'exploitation sous-jacent. Cela est particulièrement important pour Android, puisqu'il y a une quantité finie d'instances OpenCore pour la lecture du média. Les applications doivent appeler le `release` fonction pour tout `Media` ressource qui n'est plus nécessaire.
-
- Media.Release() ;
-
-
-### Exemple court
-
- Lecteur audio / / var my_media = new Media (src, onSuccess, onError) ;
-
- my_media.Play() ;
- my_media.Stop() ;
- my_media.Release() ;
-
-
-## media.seekTo
-
-Définit la position actuelle dans un fichier audio.
-
- media.seekTo(milliseconds) ;
-
-
-### Paramètres
-
- * **milliseconds** : la nouvelle position de lecture au sein du fichier audio, en millisecondes.
-
-### Exemple court
-
- Lecteur audio / / var my_media = new Media (src, onSuccess, onError) ;
- my_media.Play() ;
- SeekTo à 10 secondes après 5 secondes setTimeout(function() {my_media.seekTo(10000);}, 5000) ;
-
-
-### BlackBerry 10 Quirks
-
- * Cette méthode n'est pas prise en charge sur les périphériques BlackBerry OS 5.
-
-## media.setVolume
-
-Régler le volume du fichier audio.
-
- media.setVolume(volume) ;
-
-
-### Paramètres
-
- * **volume** : le volume à utiliser pour la lecture. La valeur doit être comprise entre 0.0 et 1.0 inclus.
-
-### Plates-formes supportées
-
- * Android
- * iOS
-
-### Exemple court
-
- Lire les données audio / / function playAudio(url) {/ / lire le fichier audio à my_media var url = nouveaux médias (url, / / réussite rappel function() {console.log ("playAudio (): Audio succès") ;
- }, / / erreur rappel function(err) {console.log ("playAudio (): Audio Error:" + err) ;
- });
-
- Lecture audio my_media.play() ;
-
- Couper le volume après 2 secondes setTimeout(function() {my_media.setVolume('0.0') ;
- }, 2000) ;
-
- Réglez le volume à 1.0 après 5 secondes setTimeout(function() {my_media.setVolume('1.0') ;
- }, 5000) ;
- }
-
-
-## media.startRecord
-
-Pour démarrer l'enregistrement d'un fichier audio.
-
- media.startRecord() ;
-
-
-### Plates-formes supportées
-
- * Android
- * iOS
- * Windows Phone 7 et 8
- * Windows
-
-### Exemple court
-
- Enregistrer de l'audio / / function recordAudio() {var src = « myrecording.mp3 » ;
- var mediaRec = new Media (src, / / réussite rappel function() {console.log ("recordAudio (): Audio succès") ;
- }, / / erreur rappel function(err) {console.log ("recordAudio (): Audio Error:" + err.code) ;
- });
-
- MediaRec.startRecord() audio record ;
- }
-
-
-### Quirks Android
-
- * Les appareils Android enregistrent de l'audio au format Adaptive Multi-Rate. Le nom de fichier spécifié doit donc comporter une extension *.amr*.
- * Les contrôles de volume du matériel sont câblés jusqu'au volume de médias tandis que tous les objets multimédia sont vivants. Une fois créé le dernier objet multimédia a `release()` appelé à ce sujet, les contrôles de volume revenir à leur comportement par défaut. Les contrôles sont également réinitialisés sur la navigation de la page, car cela libère tous les objets multimédias.
-
-### Notes au sujet d'iOS
-
- * iOS produit uniquement des enregistrements sous la forme de fichier de type *.wav* et renvoie une erreur si l'extension du nom de fichier est incorrecte.
-
- * Si un chemin d'accès complet n'est pas précisé, l'enregistrement est placé dans le répertoire `documents/tmp` correspondant à l'application. Il sera ensuite accessible via l'API `File` en utilisant la constante `LocalFileSystem.TEMPORARY`. Tout sous-répertoire présent dans le chemin d'accès au moment de l'enregistrement doit déjà exister.
-
- * Les fichiers peuvent être enregistrés et lus à l'aide de l'URI des documents :
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Bizarreries de Windows
-
- * Les périphériques Windows peuvent utiliser MP3, M4A et WMA formats pour enregistrement audio. Toutefois, dans la plupart des cas, il n'est pas possible d'utiliser le MP3 pour l'enregistrement audio sur les périphériques *Windows Phone 8.1* , car un encodeur MP3 n'est [pas livré avec Windows Phone](https://msdn.microsoft.com/en-us/library/windows/apps/windows.media.mediaproperties.mediaencodingprofile.createmp3.aspx).
-
- * Si un chemin d'accès complet n'est pas fourni, l'enregistrement est placé dans le répertoire AppData/temp. Ce qui peut être consulté le `Fichier` À l'aide de l'API `LocalFileSystem.TEMPORARY` ou ' ms-appdata : temp / / / /' URI.
-
- * Tout sous-répertoire présent dans le chemin d'accès au moment de l'enregistrement doit déjà exister.
-
-### Bizarreries de paciarelli
-
- * Pas pris en charge sur les appareils paciarelli.
-
-## media.stop
-
-Arrête la lecture d'un fichier audio.
-
- Media.Stop() ;
-
-
-### Exemple court
-
- Lire les données audio / / function playAudio(url) {/ / lire le fichier audio à my_media var url = nouveaux médias (url, / / réussite rappel function() {console.log ("playAudio (): Audio succès") ;
- }, / / erreur rappel function(err) {console.log ("playAudio (): Audio Error:" + err) ;
- }
- );
-
- Lecture audio my_media.play() ;
-
- Pause après 10 secondes setTimeout(function() {my_media.stop() ;
- }, 10000) ;
- }
-
-
-## media.stopRecord
-
-Arrête d'enregistrer un fichier audio.
-
- media.stopRecord() ;
-
-
-### Plates-formes supportées
-
- * Android
- * iOS
- * Windows Phone 7 et 8
- * Windows
-
-### Exemple court
-
- Enregistrer de l'audio / / function recordAudio() {var src = « myrecording.mp3 » ;
- var mediaRec = new Media (src, / / réussite rappel function() {console.log ("recordAudio (): Audio succès") ;
- }, / / erreur rappel function(err) {console.log ("recordAudio (): Audio Error:" + err.code) ;
- }
- );
-
- MediaRec.startRecord() audio record ;
-
- Arrêter l'enregistrement après 10 secondes setTimeout(function() {mediaRec.stopRecord() ;
- }, 10000) ;
- }
-
-
-### Bizarreries de paciarelli
-
- * Pas pris en charge sur les appareils paciarelli.
-
-## MediaError
-
-A `MediaError` objet est retourné à la `mediaError` fonction de rappel lorsqu'une erreur survient.
-
-### Propriétés
-
- * **code**: l'un des codes d'erreur prédéfinis énumérés ci-dessous.
-
- * **message**: un message d'erreur décrivant les détails de l'erreur.
-
-### Constantes
-
- * `MediaError.MEDIA_ERR_ABORTED`= 1
- * `MediaError.MEDIA_ERR_NETWORK`= 2
- * `MediaError.MEDIA_ERR_DECODE`= 3
- * `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file
diff --git a/doc/fr/index.md b/doc/fr/index.md
deleted file mode 100644
index 6a552e400..000000000
--- a/doc/fr/index.md
+++ /dev/null
@@ -1,400 +0,0 @@
-
-
-# cordova-plugin-media
-
-Ce plugin permet d'enregistrer et de lire des fichiers audio sur un périphérique.
-
-**Remarque**: l'implémentation actuelle n'est pas conforme à une spécification du W3C pour la capture de médias et est fournie pour plus de commodité seulement. Une prochaine implémentation adhèrera à la toute dernière spécification du W3C, ce qui aura probablement pour effet de déprécier l'API actuelle.
-
-Ce plugin définit un global `Media` constructeur.
-
-Bien que dans la portée globale, il n'est pas disponible jusqu'après la `deviceready` événement.
-
- document.addEventListener (« deviceready », onDeviceReady, false) ;
- function onDeviceReady() {console.log(Media);}
-
-
-## Installation
-
- Cordova plugin ajouter cordova-plugin-media
-
-
-## Plates-formes prises en charge
-
-* Android
-* BlackBerry 10
-* iOS
-* Windows Phone 7 et 8
-* Paciarelli
-* Windows
-
-## Windows Phone Quirks
-
-* Un seul fichier média peut être lu à la fois.
-
-* Il y a des restrictions strictes concernant la façon dont votre application interagit avec d'autres médias. Consultez la [documentation de Microsoft pour plus d'informations][1].
-
- [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx
-
-## Media
-
- médias var = new Media (src, mediaSuccess, [mediaError], [mediaStatus]) ;
-
-
-### Paramètres
-
-* **src** : l'URI du contenu audio. *(DOMString)*
-
-* **mediaSuccess** : (facultative) la fonction callback exécutée après que la lecture en cours, l'action d'enregistrement ou l'arrêt de lecture de l'objet `Media` soit terminée. *(Function)*
-
-* **mediaError** : (facultative) la fonction callback exécutée si une erreur survient. *(Function)*
-
-* **mediaStatus** : (facultative) la fonction callback exécutée lors de chaque changement d'état. *(Function)*
-
-### Constantes
-
-Les constantes suivantes sont déclarées comme le seul paramètre à la `mediaStatus` Rappel :
-
-* `Media.MEDIA_NONE` = 0;
-* `Media.MEDIA_STARTING` = 1;
-* `Media.MEDIA_RUNNING` = 2;
-* `Media.MEDIA_PAUSED` = 3;
-* `Media.MEDIA_STOPPED` = 4;
-
-### Méthodes
-
-* `media.getCurrentPosition` : retourne la position de lecture dans un fichier audio.
-
-* `media.getDuration`: retourne la durée d'un fichier audio.
-
-* `media.play` : permet de commencer ou reprendre la lecture d'un fichier audio.
-
-* `media.pause` : interrompt la lecture d'un fichier audio.
-
-* `media.release` : libère les ressources audio correspondantes du système d'exploitation.
-
-* `media.seekTo` : déplace la position de lecture au sein du fichier audio.
-
-* `media.setVolume` : permet de régler le volume du clip audio.
-
-* `media.startRecord` : commence l'enregistrement d'un fichier audio.
-
-* `media.stopRecord` : arrête l'enregistrement d'un fichier audio.
-
-* `media.stop` : arrête la lecture d'un fichier audio.
-
-### Paramètres supplémentaires en lecture seule
-
-* **position** : la position de lecture sein du clip audio, en secondes.
-
- * La valeur n'est pas automatiquement rafraichie pendant la lecture ; un appel à `getCurrentPosition` permet sa mise à jour.
-
-* **duration** : la durée du média, en secondes.
-
-## media.getCurrentPosition
-
-Retourne la position courante dans un fichier audio. Met également à jour la `Media` de l'objet `position` paramètre.
-
- media.getCurrentPosition (mediaSuccess, [mediaError]) ;
-
-
-### Paramètres
-
-* **mediaSuccess** : la fonction callback à laquelle est transmise la position actuelle exprimée en secondes.
-
-* **mediaError** : (facultative) la fonction callback exécutée si une erreur se produit.
-
-### Petit exemple
-
- Lecteur audio / / var my_media = new Media (src, onSuccess, onError) ;
-
- Mise à jour media positionner chaque deuxième mediaTimer de var = setInterval(function () {/ / get médias position my_media.getCurrentPosition (/ / fonction de rappel réussi (position) {si (position > -1) {console.log((position) + "secondes") ;
- }}, / / fonction de rappel d'erreur (e) {console.log ("Error getting pos =" + e) ;
- }
- );
- }, 1000) ;
-
-
-## media.getDuration
-
-Retourne la durée d'un fichier audio en quelques secondes. Si on ne connaît pas la durée, elle retourne la valeur -1.
-
- media.getDuration() ;
-
-
-### Petit exemple
-
- Lecteur audio / / var my_media = new Media (src, onSuccess, onError) ;
-
- Obtenez durée var compteur = 0 ;
- var timerDur = setInterval(function() {Compteur = compteur + 100 ;
- Si (contrer > 2000) {clearInterval(timerDur) ;
- } var dur = my_media.getDuration() ;
- Si (dur > 0) {clearInterval(timerDur) ;
- document.getElementById('audio_duration').innerHTML = (dur) + "secondes" ;
- }}, 100) ;
-
-
-## media.pause
-
-Suspendre la lecture d'un fichier audio.
-
- Media.pause() ;
-
-
-### Petit exemple
-
- Lire les données audio / / function playAudio(url) {/ / lire le fichier audio à my_media var url = nouveaux médias (url, / / fonction de rappel réussi () {console.log ("playAudio (): Audio succès");}, / / fonction de rappel d'erreur (err) {console.log ("playAudio (): erreur Audio:" + err);}) ;
-
- Lecture audio my_media.play() ;
-
- Pause après 10 secondes setTimeout (function () {media.pause() ;
- }, 10000) ;
- }
-
-
-## media.play
-
-Commence ou reprend la lecture d'un fichier audio.
-
- Media.Play() ;
-
-
-### Petit exemple
-
- Lire les données audio / / function playAudio(url) {/ / lire le fichier audio à url var my_media = new Media (url, / / fonction de rappel réussi () {console.log ("playAudio (): Audio succès") ;
- }, / / fonction de rappel d'erreur (err) {console.log ("playAudio (): Audio Error:" + err) ;
- }
- );
- Lecture audio my_media.play() ;
- }
-
-
-### iOS Quirks
-
-* **numberOfLoops** : transmettre cette option à la méthode `play` permet de spécifier le nombre de lectures à la suite d'un fichier donné, par exemple :
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
-* **playAudioWhenScreenIsLocked** : transmettre cette option à la méthode `play` permet de spécifier si la lecture doit continuer même lorsque l'écran de l'appareil est verrouillé. Si la valeur est `true` (par défaut), le bouton matériel mute est ignoré, par exemple :
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
-* **ordre de recherche de fichier** : si un nom de fichier ou chemin d'accès simple est fourni, iOS recherche d'abord le fichier correspondant dans le répertoire `www`, puis dans le répertoire `documents/tmp` appartenant à l'application :
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // recherche d'abord le fichier www/audio/beer.mp3 puis /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-Libère les ressources audio du système d'exploitation sous-jacent. Cela est particulièrement important pour Android, puisqu'il y a une quantité finie d'instances OpenCore pour la lecture du média. Les applications doivent appeler le `release` fonction pour tout `Media` ressource qui n'est plus nécessaire.
-
- Media.Release() ;
-
-
-### Petit exemple
-
- Lecteur audio / / var my_media = new Media (src, onSuccess, onError) ;
-
- my_media.Play() ;
- my_media.Stop() ;
- my_media.Release() ;
-
-
-## media.seekTo
-
-Définit la position actuelle dans un fichier audio.
-
- media.seekTo(milliseconds) ;
-
-
-### Paramètres
-
-* **milliseconds** : la nouvelle position de lecture au sein du fichier audio, en millisecondes.
-
-### Petit exemple
-
- Lecteur audio / / var my_media = new Media (src, onSuccess, onError) ;
- my_media.Play() ;
- SeekTo à 10 secondes après 5 secondes setTimeout(function() {my_media.seekTo(10000);}, 5000) ;
-
-
-### BlackBerry 10 Quirks
-
-* Cette méthode n'est pas prise en charge sur les périphériques BlackBerry OS 5.
-
-## media.setVolume
-
-Régler le volume du fichier audio.
-
- media.setVolume(volume) ;
-
-
-### Paramètres
-
-* **volume** : le volume à utiliser pour la lecture. La valeur doit être comprise entre 0.0 et 1.0 inclus.
-
-### Plates-formes prises en charge
-
-* Android
-* iOS
-
-### Petit exemple
-
- Lire les données audio / / function playAudio(url) {/ / lire le fichier audio à my_media var url = nouveaux médias (url, / / réussite rappel function() {console.log ("playAudio (): Audio succès") ;
- }, / / erreur rappel function(err) {console.log ("playAudio (): Audio Error:" + err) ;
- });
-
- Lecture audio my_media.play() ;
-
- Couper le volume après 2 secondes setTimeout(function() {my_media.setVolume('0.0') ;
- }, 2000) ;
-
- Réglez le volume à 1.0 après 5 secondes setTimeout(function() {my_media.setVolume('1.0') ;
- }, 5000) ;
- }
-
-
-## media.startRecord
-
-Pour démarrer l'enregistrement d'un fichier audio.
-
- media.startRecord() ;
-
-
-### Plates-formes prises en charge
-
-* Android
-* iOS
-* Windows Phone 7 et 8
-* Windows
-
-### Petit exemple
-
- Enregistrer de l'audio / / function recordAudio() {var src = « myrecording.mp3 » ;
- var mediaRec = new Media (src, / / réussite rappel function() {console.log ("recordAudio (): Audio succès") ;
- }, / / erreur rappel function(err) {console.log ("recordAudio (): Audio Error:" + err.code) ;
- });
-
- MediaRec.startRecord() audio record ;
- }
-
-
-### Quirks Android
-
-* Les appareils Android enregistrent de l'audio au format Adaptive Multi-Rate. Le nom de fichier spécifié doit donc comporter une extension *.amr*.
-* Les contrôles de volume du matériel sont câblés jusqu'au volume de médias tandis que tous les objets multimédia sont vivants. Une fois créé le dernier objet multimédia a `release()` appelé à ce sujet, les contrôles de volume revenir à leur comportement par défaut. Les contrôles sont également réinitialisés sur la navigation de la page, car cela libère tous les objets multimédias.
-
-### iOS Quirks
-
-* iOS produit uniquement des enregistrements sous la forme de fichier de type *.wav* et renvoie une erreur si l'extension du nom de fichier est incorrecte.
-
-* Si un chemin d'accès complet n'est pas précisé, l'enregistrement est placé dans le répertoire `documents/tmp` correspondant à l'application. Il sera ensuite accessible via l'API `File` en utilisant la constante `LocalFileSystem.TEMPORARY`. Tout sous-répertoire présent dans le chemin d'accès au moment de l'enregistrement doit déjà exister.
-
-* Les fichiers peuvent être enregistrés et lus à l'aide de l'URI des documents :
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Bizarreries de Windows
-
-* Si un chemin d'accès complet n'est pas fourni, l'enregistrement est placé dans le répertoire AppData/temp. Ce qui peut être consulté le `Fichier` À l'aide de l'API `LocalFileSystem.TEMPORARY` ou ' ms-appdata : temp / / / /' URI.
-
-* N'importe quel sous-répertoire spécifié au moment de l'enregistrement doit déjà exister.
-
-### Bizarreries de paciarelli
-
-* Pas pris en charge sur les appareils paciarelli.
-
-## media.stop
-
-Arrête la lecture d'un fichier audio.
-
- Media.Stop() ;
-
-
-### Petit exemple
-
- Lire les données audio / / function playAudio(url) {/ / lire le fichier audio à my_media var url = nouveaux médias (url, / / réussite rappel function() {console.log ("playAudio (): Audio succès") ;
- }, / / erreur rappel function(err) {console.log ("playAudio (): Audio Error:" + err) ;
- }
- );
-
- Lecture audio my_media.play() ;
-
- Pause après 10 secondes setTimeout(function() {my_media.stop() ;
- }, 10000) ;
- }
-
-
-## media.stopRecord
-
-Arrête d'enregistrer un fichier audio.
-
- media.stopRecord() ;
-
-
-### Plates-formes prises en charge
-
-* Android
-* iOS
-* Windows Phone 7 et 8
-* Windows
-
-### Petit exemple
-
- Enregistrer de l'audio / / function recordAudio() {var src = « myrecording.mp3 » ;
- var mediaRec = new Media (src, / / réussite rappel function() {console.log ("recordAudio (): Audio succès") ;
- }, / / erreur rappel function(err) {console.log ("recordAudio (): Audio Error:" + err.code) ;
- }
- );
-
- MediaRec.startRecord() audio record ;
-
- Arrêter l'enregistrement après 10 secondes setTimeout(function() {mediaRec.stopRecord() ;
- }, 10000) ;
- }
-
-
-### Bizarreries de paciarelli
-
-* Pas pris en charge sur les appareils paciarelli.
-
-## MediaError
-
-A `MediaError` objet est retourné à la `mediaError` fonction de rappel lorsqu'une erreur survient.
-
-### Propriétés
-
-* **code**: l'un des codes d'erreur prédéfinis énumérés ci-dessous.
-
-* **message**: un message d'erreur décrivant les détails de l'erreur.
-
-### Constantes
-
-* `MediaError.MEDIA_ERR_ABORTED`= 1
-* `MediaError.MEDIA_ERR_NETWORK`= 2
-* `MediaError.MEDIA_ERR_DECODE`= 3
-* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
diff --git a/doc/it/README.md b/doc/it/README.md
deleted file mode 100644
index f99ef3736..000000000
--- a/doc/it/README.md
+++ /dev/null
@@ -1,509 +0,0 @@
-
-
-# cordova-plugin-media
-
-[](https://travis-ci.org/apache/cordova-plugin-media)
-
-Questo plugin consente di registrare e riprodurre i file audio su un dispositivo.
-
-**Nota**: l'implementazione attuale non aderisce a una specifica del W3C per l'acquisizione di mezzi e viene fornito solo per comodità. Una futura realizzazione aderirà alla specifica W3C più recente e può deprecare le API corrente.
-
-Questo plugin definisce un costruttore `Media` globale.
-
-Anche se in ambito globale, non è disponibile fino a dopo l'evento `deviceready`.
-
- document.addEventListener("deviceready", onDeviceReady, false);
- function onDeviceReady() {
- console.log(Media);
- }
-
-
-## Installazione
-
- cordova plugin add cordova-plugin-media
-
-
-## Piattaforme supportate
-
- * Android
- * BlackBerry 10
- * iOS
- * Windows Phone 7 e 8
- * Tizen
- * Windows 8
- * Windows
- * Browser
-
-## Stranezze di Windows Phone
-
- * File sola multimediale può essere riprodotti in un momento.
-
- * Ci sono severe restrizioni su come l'applicazione interagisce con altri media. Vedere la [documentazione di Microsoft per maggiori dettagli](http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx).
-
-## Media
-
- var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### Parametri
-
- * **src**: un URI contenente il contenuto audio. *(DOMString)*
-
- * **mediaSuccess**: (facoltativo) il callback che viene eseguito dopo un `Media` oggetto ha completato il gioco corrente, record o interrompere l'azione. *(Funzione)*
-
- * **errore mediaError**: (facoltativo) il callback che viene eseguito se si verifica un errore. *(Funzione)*
-
- * **mediaStatus**: (facoltativo) il callback che viene eseguito per indicare i cambiamenti di stato. *(Funzione)*
-
-### Costanti
-
-Costanti sono segnalate come unico parametro al metodo di callback `mediaStatus`:
-
- * `Media.MEDIA_NONE` = 0;
- * `Media.MEDIA_STARTING` = 1;
- * `Media.MEDIA_RUNNING` = 2;
- * `Media.MEDIA_PAUSED` = 3;
- * `Media.MEDIA_STOPPED` = 4;
-
-### Metodi
-
- * `media.getCurrentPosition`: Restituisce la posizione corrente all'interno di un file audio.
-
- * `media.getDuration`: Restituisce la durata di un file audio.
-
- * `media.play`: Iniziare o riprendere la riproduzione di un file audio.
-
- * `media.pause`: Pausa la riproduzione di un file audio.
-
- * `media.release`: Libera risorse audio del sistema operativo sottostante.
-
- * `media.seekTo`: Sposta la posizione all'interno del file audio.
-
- * `media.setVolume`: Impostare il volume per la riproduzione audio.
-
- * `media.startRecord`: Iniziare a registrare un file audio.
-
- * `media.stopRecord`: Interrompere la registrazione di un file audio.
-
- * `media.stop`: Interrompere la riproduzione di un file audio.
-
-### Parametri supplementari ReadOnly
-
- * **posizione**: la posizione all'interno della riproduzione audio, in pochi secondi.
-
- * Non aggiornate automaticamente durante il gioco; chiamare `getCurrentPosition` per l'aggiornamento.
-
- * **durata**: la durata dei media, in secondi.
-
-## media.getCurrentPosition
-
-Restituisce la posizione corrente all'interno di un file audio. Aggiorna anche il parametro di `position` dell'oggetto `Media`.
-
- media.getCurrentPosition(mediaSuccess, [mediaError]);
-
-
-### Parametri
-
- * **mediaSuccess**: il callback passato la posizione corrente in pochi secondi.
-
- * **errore mediaError**: (facoltativo) il callback da eseguire se si verifica un errore.
-
-### Esempio rapido
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Update media position every second
- var mediaTimer = setInterval(function () {
- // get media position
- my_media.getCurrentPosition(
- // success callback
- function (position) {
- if (position > -1) {
- console.log((position) + " sec");
- }
- },
- // error callback
- function (e) {
- console.log("Error getting pos=" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-Restituisce la durata di un file audio in secondi. Se la durata è sconosciuta, essa restituisce un valore di -1.
-
- media.getDuration();
-
-
-### Esempio rapido
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(function() {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = my_media.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + " sec";
- }
- }, 100);
-
-
-## Media.pause
-
-Sospende la riproduzione di un file audio.
-
- media.pause();
-
-
-### Esempio rapido
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () { console.log("playAudio():Audio Success"); },
- // error callback
- function (err) { console.log("playAudio():Audio Error: " + err); }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function () {
- media.pause();
- }, 10000);
- }
-
-
-## Media.Play
-
-Avvia o riprende la riproduzione di un file audio.
-
- media.play();
-
-
-### Esempio rapido
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function (err) {
- console.log("playAudio():Audio Error: " + err);
- }
- );
- // Play audio
- my_media.play();
- }
-
-
-### iOS stranezze
-
- * **numberOfLoops**: passare questa opzione per il `play` metodo per specificare il numero di volte desiderato file multimediale per riprodurre, ad esempio:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
- * **playAudioWhenScreenIsLocked**: questa opzione per passare il `play` metodo per specificare se si desidera consentire la riproduzione quando lo schermo è bloccato. Se impostato su `true` (il valore predefinito), viene ignorato lo stato del pulsante mute hardware, ad esempio:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
- * **ordine di ricerca di file**: quando viene fornito solo un nome file o percorso semplice, cerca in iOS il `www` directory per il file, quindi l'applicazione `documents/tmp` directory:
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-Rilascia le risorse audio del sistema operativo sottostante. Ciò è particolarmente importante per Android, dato che ci sono una quantità finita di OpenCore istanze per la riproduzione multimediale. Le applicazioni devono chiamare la funzione di `release` qualsiasi risorsa `Media` non è più necessario.
-
- media.release();
-
-
-### Esempio rapido
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- my_media.play();
- my_media.stop();
- my_media.release();
-
-
-## media.seekTo
-
-Imposta la posizione corrente all'interno di un file audio.
-
- media.seekTo(milliseconds);
-
-
-### Parametri
-
- * **millisecondi**: posizione per impostare la posizione di riproduzione all'interno l'audio, in millisecondi.
-
-### Esempio rapido
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
- my_media.play();
- // SeekTo to 10 seconds after 5 seconds
- setTimeout(function() {
- my_media.seekTo(10000);
- }, 5000);
-
-
-### BlackBerry 10 capricci
-
- * Non è supportato sui dispositivi BlackBerry OS 5.
-
-## media.setVolume
-
-Impostare il volume per un file audio.
-
- media.setVolume(volume);
-
-
-### Parametri
-
- * **volume**: il volume impostato per la riproduzione. Il valore deve essere all'interno della gamma di 0,0 e 1,0.
-
-### Piattaforme supportate
-
- * Android
- * iOS
-
-### Esempio rapido
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- });
-
- // Play audio
- my_media.play();
-
- // Mute volume after 2 seconds
- setTimeout(function() {
- my_media.setVolume('0.0');
- }, 2000);
-
- // Set volume to 1.0 after 5 seconds
- setTimeout(function() {
- my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-Avvia la registrazione di un file audio.
-
- media.startRecord();
-
-
-### Piattaforme supportate
-
- * Android
- * iOS
- * Windows Phone 7 e 8
- * Windows
-
-### Esempio rapido
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- });
-
- // Record audio
- mediaRec.startRecord();
- }
-
-
-### Stranezze Android
-
- * Dispositivi Android registrano audio in formato Adaptive Multi-Rate. Il file specificato deve terminare con l'estensione ** .
- * I controlli di volume di hardware sono cablati a volume media mentre eventuali oggetti multimediali sono vivi. Una volta l'ultimi Media creati oggetto ha `release()` chiamato su di esso, i controlli di volume di tornare alla loro comportamento predefinito. I controlli vengono reimpostati anche sulla pagina di navigazione, come questo rilascia tutti gli oggetti multimediali.
-
-### iOS stranezze
-
- * iOS solo i record per i file di tipo *WAV* e restituisce un errore se il file di nome estensione è non corretto.
-
- * Se non è specificato un percorso completo, la registrazione viene inserita nell'applicazione `documents/tmp` directory. Questo si può accedere tramite il `File` API utilizzando `LocalFileSystem.TEMPORARY` . Deve esistere alcuna sottodirectory specificate a tempo di record.
-
- * I file possono essere registrati e giocati indietro usando i documenti URI:
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Stranezze di Windows
-
- * Dispositivi Windows possono utilizzare MP3, M4A e WMA formati per l'audio registrato. Tuttavia, nella maggior parte dei casi non è possibile utilizzare MP3 per la registrazione audio su dispositivi *Windows Phone 8.1* , perché un encoder MP3 è [non forniti con Windows Phone](https://msdn.microsoft.com/en-us/library/windows/apps/windows.media.mediaproperties.mediaencodingprofile.createmp3.aspx).
-
- * Se non è specificato un percorso completo, la registrazione viene inserita nella directory AppData/temp. Questo si può accedere tramite il `File` Utilizzando API `LocalFileSystem.TEMPORARY` o ' ms-appdata: / / temp /' URI.
-
- * Deve esistere alcuna sottodirectory specificate a tempo di record.
-
-### Tizen stranezze
-
- * Tizen periferiche non supportano.
-
-## media.stop
-
-Interrompe la riproduzione di un file audio.
-
- media.stop();
-
-
-### Esempio rapido
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function() {
- my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-Smette di registrare un file audio.
-
- media.stopRecord();
-
-
-### Piattaforme supportate
-
- * Android
- * iOS
- * Windows Phone 7 e 8
- * Windows
-
-### Esempio rapido
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- }
- );
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 seconds
- setTimeout(function() {
- mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### Tizen stranezze
-
- * Tizen periferiche non supportano.
-
-## Errore MediaError
-
-Un oggetto ` MediaError` viene restituito alla funzione di callback ` mediaError` quando si verifica un errore.
-
-### Proprietà
-
- * **codice**: uno dei codici di errore predefiniti elencati di seguito.
-
- * **messaggio**: un messaggio di errore che descrive i dettagli dell'errore.
-
-### Costanti
-
- * `MediaError.MEDIA_ERR_ABORTED`= 1
- * `MediaError.MEDIA_ERR_NETWORK`= 2
- * `MediaError.MEDIA_ERR_DECODE`= 3
- * `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file
diff --git a/doc/it/index.md b/doc/it/index.md
deleted file mode 100644
index 2999f844e..000000000
--- a/doc/it/index.md
+++ /dev/null
@@ -1,505 +0,0 @@
-
-
-# cordova-plugin-media
-
-Questo plugin consente di registrare e riprodurre i file audio su un dispositivo.
-
-**Nota**: l'implementazione attuale non aderisce a una specifica del W3C per l'acquisizione di mezzi e viene fornito solo per comodità. Una futura realizzazione aderirà alla specifica W3C più recente e può deprecare le API corrente.
-
-Questo plugin definisce un costruttore `Media` globale.
-
-Anche se in ambito globale, non è disponibile fino a dopo l'evento `deviceready`.
-
- document.addEventListener("deviceready", onDeviceReady, false);
- function onDeviceReady() {
- console.log(Media);
- }
-
-
-## Installazione
-
- cordova plugin add cordova-plugin-media
-
-
-## Piattaforme supportate
-
-* Android
-* BlackBerry 10
-* iOS
-* Windows Phone 7 e 8
-* Tizen
-* Windows
-
-## Stranezze di Windows Phone
-
-* File sola multimediale può essere riprodotti in un momento.
-
-* Ci sono severe restrizioni su come l'applicazione interagisce con altri media. Vedere la [documentazione di Microsoft per maggiori dettagli][1].
-
- [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx
-
-## Media
-
- var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### Parametri
-
-* **src**: un URI contenente il contenuto audio. *(DOMString)*
-
-* **mediaSuccess**: (facoltativo) il callback che viene eseguito dopo un `Media` oggetto ha completato il gioco corrente, record o interrompere l'azione. *(Funzione)*
-
-* **errore mediaError**: (facoltativo) il callback che viene eseguito se si verifica un errore. *(Funzione)*
-
-* **mediaStatus**: (facoltativo) il callback che viene eseguito per indicare i cambiamenti di stato. *(Funzione)*
-
-### Costanti
-
-Costanti sono segnalate come unico parametro al metodo di callback `mediaStatus`:
-
-* `Media.MEDIA_NONE` = 0;
-* `Media.MEDIA_STARTING` = 1;
-* `Media.MEDIA_RUNNING` = 2;
-* `Media.MEDIA_PAUSED` = 3;
-* `Media.MEDIA_STOPPED` = 4;
-
-### Metodi
-
-* `media.getCurrentPosition`: Restituisce la posizione corrente all'interno di un file audio.
-
-* `media.getDuration`: Restituisce la durata di un file audio.
-
-* `media.play`: Iniziare o riprendere la riproduzione di un file audio.
-
-* `media.pause`: Pausa la riproduzione di un file audio.
-
-* `media.release`: Libera risorse audio del sistema operativo sottostante.
-
-* `media.seekTo`: Sposta la posizione all'interno del file audio.
-
-* `media.setVolume`: Impostare il volume per la riproduzione audio.
-
-* `media.startRecord`: Iniziare a registrare un file audio.
-
-* `media.stopRecord`: Interrompere la registrazione di un file audio.
-
-* `media.stop`: Interrompere la riproduzione di un file audio.
-
-### Parametri supplementari ReadOnly
-
-* **posizione**: la posizione all'interno della riproduzione audio, in pochi secondi.
-
- * Non aggiornate automaticamente durante il gioco; chiamare `getCurrentPosition` per l'aggiornamento.
-
-* **durata**: la durata dei media, in secondi.
-
-## media.getCurrentPosition
-
-Restituisce la posizione corrente all'interno di un file audio. Aggiorna anche il parametro di `position` dell'oggetto `Media`.
-
- media.getCurrentPosition(mediaSuccess, [mediaError]);
-
-
-### Parametri
-
-* **mediaSuccess**: il callback passato la posizione corrente in pochi secondi.
-
-* **errore mediaError**: (facoltativo) il callback da eseguire se si verifica un errore.
-
-### Esempio rapido
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Update media position every second
- var mediaTimer = setInterval(function () {
- // get media position
- my_media.getCurrentPosition(
- // success callback
- function (position) {
- if (position > -1) {
- console.log((position) + " sec");
- }
- },
- // error callback
- function (e) {
- console.log("Error getting pos=" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-Restituisce la durata di un file audio in secondi. Se la durata è sconosciuta, essa restituisce un valore di -1.
-
- media.getDuration();
-
-
-### Esempio rapido
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(function() {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = my_media.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + " sec";
- }
- }, 100);
-
-
-## Media.pause
-
-Sospende la riproduzione di un file audio.
-
- media.pause();
-
-
-### Esempio rapido
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () { console.log("playAudio():Audio Success"); },
- // error callback
- function (err) { console.log("playAudio():Audio Error: " + err); }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function () {
- media.pause();
- }, 10000);
- }
-
-
-## Media.Play
-
-Avvia o riprende la riproduzione di un file audio.
-
- media.play();
-
-
-### Esempio rapido
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function (err) {
- console.log("playAudio():Audio Error: " + err);
- }
- );
- // Play audio
- my_media.play();
- }
-
-
-### iOS stranezze
-
-* **numberOfLoops**: passare questa opzione per il `play` metodo per specificare il numero di volte desiderato file multimediale per riprodurre, ad esempio:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
-* **playAudioWhenScreenIsLocked**: questa opzione per passare il `play` metodo per specificare se si desidera consentire la riproduzione quando lo schermo è bloccato. Se impostato su `true` (il valore predefinito), viene ignorato lo stato del pulsante mute hardware, ad esempio:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
-* **ordine di ricerca di file**: quando viene fornito solo un nome file o percorso semplice, cerca in iOS il `www` directory per il file, quindi l'applicazione `documents/tmp` directory:
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-Rilascia le risorse audio del sistema operativo sottostante. Ciò è particolarmente importante per Android, dato che ci sono una quantità finita di OpenCore istanze per la riproduzione multimediale. Le applicazioni devono chiamare la funzione di `release` qualsiasi risorsa `Media` non è più necessario.
-
- media.release();
-
-
-### Esempio rapido
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- my_media.play();
- my_media.stop();
- my_media.release();
-
-
-## media.seekTo
-
-Imposta la posizione corrente all'interno di un file audio.
-
- media.seekTo(milliseconds);
-
-
-### Parametri
-
-* **millisecondi**: posizione per impostare la posizione di riproduzione all'interno l'audio, in millisecondi.
-
-### Esempio rapido
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
- my_media.play();
- // SeekTo to 10 seconds after 5 seconds
- setTimeout(function() {
- my_media.seekTo(10000);
- }, 5000);
-
-
-### BlackBerry 10 capricci
-
-* Non è supportato sui dispositivi BlackBerry OS 5.
-
-## media.setVolume
-
-Impostare il volume per un file audio.
-
- media.setVolume(volume);
-
-
-### Parametri
-
-* **volume**: il volume impostato per la riproduzione. Il valore deve essere all'interno della gamma di 0,0 e 1,0.
-
-### Piattaforme supportate
-
-* Android
-* iOS
-
-### Esempio rapido
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- });
-
- // Play audio
- my_media.play();
-
- // Mute volume after 2 seconds
- setTimeout(function() {
- my_media.setVolume('0.0');
- }, 2000);
-
- // Set volume to 1.0 after 5 seconds
- setTimeout(function() {
- my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-Avvia la registrazione di un file audio.
-
- media.startRecord();
-
-
-### Piattaforme supportate
-
-* Android
-* iOS
-* Windows Phone 7 e 8
-* Windows
-
-### Esempio rapido
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- });
-
- // Record audio
- mediaRec.startRecord();
- }
-
-
-### Stranezze Android
-
-* Dispositivi Android registrano audio in formato Adaptive Multi-Rate. Il file specificato deve terminare con l'estensione ** .
-* I controlli di volume di hardware sono cablati a volume media mentre eventuali oggetti multimediali sono vivi. Una volta l'ultimi Media creati oggetto ha `release()` chiamato su di esso, i controlli di volume di tornare alla loro comportamento predefinito. I controlli vengono reimpostati anche sulla pagina di navigazione, come questo rilascia tutti gli oggetti multimediali.
-
-### iOS stranezze
-
-* iOS solo i record per i file di tipo *WAV* e restituisce un errore se il file di nome estensione è non corretto.
-
-* Se non è specificato un percorso completo, la registrazione viene inserita nell'applicazione `documents/tmp` directory. Questo si può accedere tramite il `File` API utilizzando `LocalFileSystem.TEMPORARY` . Deve esistere alcuna sottodirectory specificate a tempo di record.
-
-* I file possono essere registrati e giocati indietro usando i documenti URI:
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Stranezze di Windows
-
-* Se non è specificato un percorso completo, la registrazione viene inserita nella directory AppData/temp. Questo si può accedere tramite il `File` Utilizzando API `LocalFileSystem.TEMPORARY` o ' ms-appdata: / / temp /' URI.
-
-* Deve esistere alcuna sottodirectory specificate a tempo di record.
-
-### Tizen stranezze
-
-* Tizen periferiche non supportano.
-
-## media.stop
-
-Interrompe la riproduzione di un file audio.
-
- media.stop();
-
-
-### Esempio rapido
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function() {
- my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-Smette di registrare un file audio.
-
- media.stopRecord();
-
-
-### Piattaforme supportate
-
-* Android
-* iOS
-* Windows Phone 7 e 8
-* Windows
-
-### Esempio rapido
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- }
- );
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 seconds
- setTimeout(function() {
- mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### Tizen stranezze
-
-* Tizen periferiche non supportano.
-
-## Errore MediaError
-
-Un oggetto ` MediaError` viene restituito alla funzione di callback ` mediaError` quando si verifica un errore.
-
-### Proprietà
-
-* **codice**: uno dei codici di errore predefiniti elencati di seguito.
-
-* **messaggio**: un messaggio di errore che descrive i dettagli dell'errore.
-
-### Costanti
-
-* `MediaError.MEDIA_ERR_ABORTED`= 1
-* `MediaError.MEDIA_ERR_NETWORK`= 2
-* `MediaError.MEDIA_ERR_DECODE`= 3
-* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
diff --git a/doc/ja/README.md b/doc/ja/README.md
deleted file mode 100644
index 37de0fe07..000000000
--- a/doc/ja/README.md
+++ /dev/null
@@ -1,509 +0,0 @@
-
-
-# cordova-plugin-media
-
-[](https://travis-ci.org/apache/cordova-plugin-media)
-
-このプラグインは、記録し、デバイス上のオーディオ ファイルを再生する機能を提供します。
-
-**注**: 現在の実装では、メディアのキャプチャのための W3C 仕様に準拠していないとは便宜上提供されるだけです。 将来の実装を最新の W3C 仕様に準拠し、現在 Api をとがめることがあります。
-
-このプラグインでは、グローバル `Media` のコンス トラクターを定義します。
-
-グローバル スコープではあるがそれがないまで `deviceready` イベントの後です。
-
- document.addEventListener("deviceready", onDeviceReady, false);
- function onDeviceReady() {
- console.log(Media);
- }
-
-
-## インストール
-
- cordova plugin add cordova-plugin-media
-
-
-## サポートされているプラットフォーム
-
- * アンドロイド
- * ブラックベリー 10
- * iOS
- * Windows Phone 7 と 8
- * Tizen
- * Windows 8
- * Windows
- * ブラウザー
-
-## Windows Phone の癖
-
- * のみ 1 つのメディア ファイルは、一度に再生できます。
-
- * アプリケーションと他のメディアとの対話に厳格な制限があります。 [詳細については、Microsoft のマニュアル](http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx)を参照してください。.
-
-## メディア
-
- var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### パラメーター
-
- * **src**: オーディオのコンテンツを含む URI。*(,)*
-
- * **mediaSuccess**: (省略可能) 後に実行するコールバックを `Media` 再生用に現在、レコード、または stop アクション オブジェクトが完了しました。*(機能)*
-
- * **mediaError**: (省略可能) エラーが発生した場合に実行されるコールバック。*(機能)*
-
- * **mediaStatus**: (省略可能) 状態の変化を示すために実行されるコールバック。*(機能)*
-
-### 定数
-
-次の定数は、`mediaStatus` コールバックを唯一のパラメーターとして報告されます。
-
- * `Media.MEDIA_NONE` = 0;
- * `Media.MEDIA_STARTING` = 1;
- * `Media.MEDIA_RUNNING` = 2;
- * `Media.MEDIA_PAUSED` = 3;
- * `Media.MEDIA_STOPPED` = 4;
-
-### メソッド
-
- * `media.getCurrentPosition`: オーディオ ファイル内の現在位置を返します。
-
- * `media.getDuration`: オーディオ ファイルの継続時間を返します。
-
- * `media.play`: 開始またはオーディオ ファイルの再生を再開します。
-
- * `media.pause`: オーディオ ファイルの再生を一時停止。
-
- * `media.release`: 基になるオペレーティング システムのオーディオ リソースを解放します。
-
- * `media.seekTo`: オーディオ ファイル内の位置を移動します。
-
- * `media.setVolume`: オーディオの再生ボリュームを設定します。
-
- * `media.startRecord`: オーディオ ファイルの録音を開始します。
-
- * `media.stopRecord`: オーディオ ファイルの録音を停止します。
-
- * `media.stop`: オーディオ ファイルの再生を停止します。
-
-### 追加読み取り専用パラメーター
-
- * **位置**: 数秒でオーディオの再生では、内の位置。
-
- * 自動的に更新されません; のプレイ中にコール `getCurrentPosition` を更新します。
-
- * **期間**: 秒で、メディアの期間。
-
-## media.getCurrentPosition
-
-オーディオ ファイル内の現在位置を返します。また、`Media` オブジェクトの `position` パラメーターを更新します。
-
- media.getCurrentPosition(mediaSuccess, [mediaError]);
-
-
-### パラメーター
-
- * **mediaSuccess**: 秒の現在の位置を渡されるコールバック。
-
- * **mediaError**: (省略可能) コールバックでエラーが発生した場合に実行します。
-
-### 簡単な例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Update media position every second
- var mediaTimer = setInterval(function () {
- // get media position
- my_media.getCurrentPosition(
- // success callback
- function (position) {
- if (position > -1) {
- console.log((position) + " sec");
- }
- },
- // error callback
- function (e) {
- console.log("Error getting pos=" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-オーディオ ファイルの継続時間 (秒単位) を返します。期間は知られている、-1 の値が返されます。
-
- media.getDuration();
-
-
-### 簡単な例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(function() {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = my_media.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + " sec";
- }
- }, 100);
-
-
-## media.pause
-
-オーディオ ファイルの再生を一時停止します。
-
- media.pause();
-
-
-### 簡単な例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () { console.log("playAudio():Audio Success"); },
- // error callback
- function (err) { console.log("playAudio():Audio Error: " + err); }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function () {
- media.pause();
- }, 10000);
- }
-
-
-## media.play
-
-開始またはオーディオ ファイルの再生を再開します。
-
- media.play();
-
-
-### 簡単な例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function (err) {
- console.log("playAudio():Audio Error: " + err);
- }
- );
- // Play audio
- my_media.play();
- }
-
-
-### iOS の癖
-
- * **numberOfLoops**: このオプションを指定して、 `play` メディア ファイルを再生する、例えば回数を指定する方法。
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
- * **playAudioWhenScreenIsLocked**: このオプションを渡す、 `play` 、画面がロックされているときに再生を許可するかどうかを指定するメソッド。 場合に設定されている `true` (既定値)、例えば、ハードウェア ミュート ボタンの状態は無視されます。
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
- * **ファイル検索の順序**: iOS の検索でファイル名または単純なパスのみが提供される場合、 `www` ディレクトリ、ファイルをアプリケーションの `documents/tmp` ディレクトリ。
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-基になるオペレーティング システムのオーディオ リソースを解放します。 メディアの再生のための OpenCore インスタンスの有限な量があるので、人造人間のため特に重要です。 アプリケーションが不要な `Media` リソースの `release` の関数を呼び出す必要があります。
-
- media.release();
-
-
-### 簡単な例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- my_media.play();
- my_media.stop();
- my_media.release();
-
-
-## media.seekTo
-
-オーディオ ファイル内の現在位置を設定します。
-
- media.seekTo(milliseconds);
-
-
-### パラメーター
-
- * **ミリ秒単位**: ミリ秒単位で、オーディオの再生位置を設定する位置。
-
-### 簡単な例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
- my_media.play();
- // SeekTo to 10 seconds after 5 seconds
- setTimeout(function() {
- my_media.seekTo(10000);
- }, 5000);
-
-
-### ブラックベリー 10 癖
-
- * ブラックベリー OS 5 デバイスでサポートされていません。
-
-## media.setVolume
-
-オーディオ ファイルの音量を設定します。
-
- media.setVolume(volume);
-
-
-### パラメーター
-
- * **ボリューム**: ボリュームの再生を設定します。値は 0.0 ~ 1.0 の範囲内である必要があります。
-
-### サポートされているプラットフォーム
-
- * アンドロイド
- * iOS
-
-### 簡単な例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- });
-
- // Play audio
- my_media.play();
-
- // Mute volume after 2 seconds
- setTimeout(function() {
- my_media.setVolume('0.0');
- }, 2000);
-
- // Set volume to 1.0 after 5 seconds
- setTimeout(function() {
- my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-オーディオ ファイルの録音を開始します。
-
- media.startRecord();
-
-
-### サポートされているプラットフォーム
-
- * アンドロイド
- * iOS
- * Windows Phone 7 と 8
- * Windows
-
-### 簡単な例
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- });
-
- // Record audio
- mediaRec.startRecord();
- }
-
-
-### Android の癖
-
- * Android 端末適応型マルチレート形式にオーディオを録音します。指定したファイルは、 *.amr*拡張子で終わる必要があります。
- * メディア オブジェクトが生きている間、ハードウェアのボリューム コントロールは有線メディア ボリュームまで。 一度 `release()` それと呼ばれるオブジェクトには最後に作成したメディア、ボリューム コントロールのデフォルトの動作に戻ります。 コントロールは、すべてのメディア オブジェクトをリリースこれとしてページ ナビゲーションにもリセットされます。
-
-### iOS の癖
-
- * iOS の種類*.wav*と返しますエラー場合は、ファイル名拡張子がファイルをレコードのみが修正されません。
-
- * 記録は、アプリケーションの配置の完全なパスを指定しない場合 `documents/tmp` ディレクトリ。 これを介してアクセスすることができます、 `File` API を使用して `LocalFileSystem.TEMPORARY` 。 記録時に指定された任意のサブディレクトリに存在する必要があります。
-
- * ファイルを記録し、再生することができますドキュメント URI を使用して。
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Windows の癖
-
- * Windows デバイスで使用できる MP3、M4A、WMA 形式は、オーディオを記録しました。 しかしほとんどの場合は不可能だ MP3 エンコーダーが[Windows Phone に付属していない](https://msdn.microsoft.com/en-us/library/windows/apps/windows.media.mediaproperties.mediaencodingprofile.createmp3.aspx)ので、 *8.1 の Windows Phone*デバイスでオーディオ録音の MP3 を使用するには.
-
- * 完全なパスを指定しない場合、記録は AppData/temp ディレクトリに配置されます。これを介してアクセスすることができます、 `ファイル` API を使用してください。 `LocalFileSystem.TEMPORARY` または ' ms appdata: temp////' URI。
-
- * 記録時に指定された任意のサブディレクトリに存在する必要があります。
-
-### Tizen の癖
-
- * Tizen のデバイスでサポートされていません。
-
-## media.stop
-
-オーディオ ファイルの再生を停止します。
-
- media.stop();
-
-
-### 簡単な例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function() {
- my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-オーディオ ファイルの録音を停止します。
-
- media.stopRecord();
-
-
-### サポートされているプラットフォーム
-
- * アンドロイド
- * iOS
- * Windows Phone 7 と 8
- * Windows
-
-### 簡単な例
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- }
- );
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 seconds
- setTimeout(function() {
- mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### Tizen の癖
-
- * Tizen のデバイスでサポートされていません。
-
-## MediaError
-
-`MediaError` オブジェクトにエラーが発生したときに `mediaError` コールバック関数に返されます。
-
-### プロパティ
-
- * **コード**: 次のいずれかの定義済みのエラー コード。
-
- * **メッセージ**: エラーの詳細を説明するエラー メッセージ。
-
-### 定数
-
- * `MediaError.MEDIA_ERR_ABORTED`= 1
- * `MediaError.MEDIA_ERR_NETWORK`= 2
- * `MediaError.MEDIA_ERR_DECODE`= 3
- * `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file
diff --git a/doc/ja/index.md b/doc/ja/index.md
deleted file mode 100644
index b092f7e6b..000000000
--- a/doc/ja/index.md
+++ /dev/null
@@ -1,505 +0,0 @@
-
-
-# cordova-plugin-media
-
-このプラグインは、記録し、デバイス上のオーディオ ファイルを再生する機能を提供します。
-
-**注**: 現在の実装では、メディアのキャプチャのための W3C 仕様に準拠していないとは便宜上提供されるだけです。 将来の実装を最新の W3C 仕様に準拠し、現在 Api をとがめることがあります。
-
-このプラグインでは、グローバル `Media` のコンス トラクターを定義します。
-
-グローバル スコープではあるがそれがないまで `deviceready` イベントの後です。
-
- document.addEventListener("deviceready", onDeviceReady, false);
- function onDeviceReady() {
- console.log(Media);
- }
-
-
-## インストール
-
- cordova plugin add cordova-plugin-media
-
-
-## サポートされているプラットフォーム
-
-* アンドロイド
-* ブラックベリー 10
-* iOS
-* Windows Phone 7 と 8
-* Tizen
-* Windows
-
-## Windows Phone の癖
-
-* のみ 1 つのメディア ファイルは、一度に再生できます。
-
-* アプリケーションと他のメディアとの対話に厳格な制限があります。 [詳細については、Microsoft のマニュアル][1]を参照してください。.
-
- [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx
-
-## メディア
-
- var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### パラメーター
-
-* **src**: オーディオのコンテンツを含む URI。*(,)*
-
-* **mediaSuccess**: (省略可能) 後に実行するコールバックを `Media` 再生用に現在、レコード、または stop アクション オブジェクトが完了しました。*(機能)*
-
-* **mediaError**: (省略可能) エラーが発生した場合に実行されるコールバック。*(機能)*
-
-* **mediaStatus**: (省略可能) 状態の変化を示すために実行されるコールバック。*(機能)*
-
-### 定数
-
-次の定数は、`mediaStatus` コールバックを唯一のパラメーターとして報告されます。
-
-* `Media.MEDIA_NONE` = 0;
-* `Media.MEDIA_STARTING` = 1;
-* `Media.MEDIA_RUNNING` = 2;
-* `Media.MEDIA_PAUSED` = 3;
-* `Media.MEDIA_STOPPED` = 4;
-
-### メソッド
-
-* `media.getCurrentPosition`: オーディオ ファイル内の現在位置を返します。
-
-* `media.getDuration`: オーディオ ファイルの継続時間を返します。
-
-* `media.play`: 開始またはオーディオ ファイルの再生を再開します。
-
-* `media.pause`: オーディオ ファイルの再生を一時停止。
-
-* `media.release`: 基になるオペレーティング システムのオーディオ リソースを解放します。
-
-* `media.seekTo`: オーディオ ファイル内の位置を移動します。
-
-* `media.setVolume`: オーディオの再生ボリュームを設定します。
-
-* `media.startRecord`: オーディオ ファイルの録音を開始します。
-
-* `media.stopRecord`: オーディオ ファイルの録音を停止します。
-
-* `media.stop`: オーディオ ファイルの再生を停止します。
-
-### 追加読み取り専用パラメーター
-
-* **位置**: 数秒でオーディオの再生では、内の位置。
-
- * 自動的に更新されません; のプレイ中にコール `getCurrentPosition` を更新します。
-
-* **期間**: 秒で、メディアの期間。
-
-## media.getCurrentPosition
-
-オーディオ ファイル内の現在位置を返します。また、`Media` オブジェクトの `position` パラメーターを更新します。
-
- media.getCurrentPosition(mediaSuccess, [mediaError]);
-
-
-### パラメーター
-
-* **mediaSuccess**: 秒の現在の位置を渡されるコールバック。
-
-* **mediaError**: (省略可能) コールバックでエラーが発生した場合に実行します。
-
-### 簡単な例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Update media position every second
- var mediaTimer = setInterval(function () {
- // get media position
- my_media.getCurrentPosition(
- // success callback
- function (position) {
- if (position > -1) {
- console.log((position) + " sec");
- }
- },
- // error callback
- function (e) {
- console.log("Error getting pos=" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-オーディオ ファイルの継続時間 (秒単位) を返します。期間は知られている、-1 の値が返されます。
-
- media.getDuration();
-
-
-### 簡単な例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(function() {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = my_media.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + " sec";
- }
- }, 100);
-
-
-## media.pause
-
-オーディオ ファイルの再生を一時停止します。
-
- media.pause();
-
-
-### 簡単な例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () { console.log("playAudio():Audio Success"); },
- // error callback
- function (err) { console.log("playAudio():Audio Error: " + err); }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function () {
- media.pause();
- }, 10000);
- }
-
-
-## media.play
-
-開始またはオーディオ ファイルの再生を再開します。
-
- media.play();
-
-
-### 簡単な例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function (err) {
- console.log("playAudio():Audio Error: " + err);
- }
- );
- // Play audio
- my_media.play();
- }
-
-
-### iOS の癖
-
-* **numberOfLoops**: このオプションを指定して、 `play` メディア ファイルを再生する、例えば回数を指定する方法。
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
-* **playAudioWhenScreenIsLocked**: このオプションを渡す、 `play` 、画面がロックされているときに再生を許可するかどうかを指定するメソッド。 場合に設定されている `true` (既定値)、例えば、ハードウェア ミュート ボタンの状態は無視されます。
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
-* **ファイル検索の順序**: iOS の検索でファイル名または単純なパスのみが提供される場合、 `www` ディレクトリ、ファイルをアプリケーションの `documents/tmp` ディレクトリ。
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-基になるオペレーティング システムのオーディオ リソースを解放します。 メディアの再生のための OpenCore インスタンスの有限な量があるので、人造人間のため特に重要です。 アプリケーションが不要な `Media` リソースの `release` の関数を呼び出す必要があります。
-
- media.release();
-
-
-### 簡単な例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- my_media.play();
- my_media.stop();
- my_media.release();
-
-
-## media.seekTo
-
-オーディオ ファイル内の現在位置を設定します。
-
- media.seekTo(milliseconds);
-
-
-### パラメーター
-
-* **ミリ秒単位**: ミリ秒単位で、オーディオの再生位置を設定する位置。
-
-### 簡単な例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
- my_media.play();
- // SeekTo to 10 seconds after 5 seconds
- setTimeout(function() {
- my_media.seekTo(10000);
- }, 5000);
-
-
-### ブラックベリー 10 癖
-
-* ブラックベリー OS 5 デバイスでサポートされていません。
-
-## media.setVolume
-
-オーディオ ファイルの音量を設定します。
-
- media.setVolume(volume);
-
-
-### パラメーター
-
-* **ボリューム**: ボリュームの再生を設定します。値は 0.0 ~ 1.0 の範囲内である必要があります。
-
-### サポートされているプラットフォーム
-
-* アンドロイド
-* iOS
-
-### 簡単な例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- });
-
- // Play audio
- my_media.play();
-
- // Mute volume after 2 seconds
- setTimeout(function() {
- my_media.setVolume('0.0');
- }, 2000);
-
- // Set volume to 1.0 after 5 seconds
- setTimeout(function() {
- my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-オーディオ ファイルの録音を開始します。
-
- media.startRecord();
-
-
-### サポートされているプラットフォーム
-
-* アンドロイド
-* iOS
-* Windows Phone 7 と 8
-* Windows
-
-### 簡単な例
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- });
-
- // Record audio
- mediaRec.startRecord();
- }
-
-
-### Android の癖
-
-* Android 端末適応型マルチレート形式にオーディオを録音します。指定したファイルは、 *.amr*拡張子で終わる必要があります。
-* メディア オブジェクトが生きている間、ハードウェアのボリューム コントロールは有線メディア ボリュームまで。 一度 `release()` それと呼ばれるオブジェクトには最後に作成したメディア、ボリューム コントロールのデフォルトの動作に戻ります。 コントロールは、すべてのメディア オブジェクトをリリースこれとしてページ ナビゲーションにもリセットされます。
-
-### iOS の癖
-
-* iOS の種類*.wav*と返しますエラー場合は、ファイル名拡張子がファイルをレコードのみが修正されません。
-
-* 記録は、アプリケーションの配置の完全なパスを指定しない場合 `documents/tmp` ディレクトリ。 これを介してアクセスすることができます、 `File` API を使用して `LocalFileSystem.TEMPORARY` 。 記録時に指定された任意のサブディレクトリに存在する必要があります。
-
-* ファイルを記録し、再生することができますドキュメント URI を使用して。
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Windows の癖
-
-* 完全なパスを指定しない場合、記録は AppData/temp ディレクトリに配置されます。これを介してアクセスすることができます、 `ファイル` API を使用してください。 `LocalFileSystem.TEMPORARY` または ' ms appdata: temp////' URI。
-
-* 記録時に指定された任意のサブディレクトリに存在する必要があります。
-
-### Tizen の癖
-
-* Tizen のデバイスでサポートされていません。
-
-## media.stop
-
-オーディオ ファイルの再生を停止します。
-
- media.stop();
-
-
-### 簡単な例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function() {
- my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-オーディオ ファイルの録音を停止します。
-
- media.stopRecord();
-
-
-### サポートされているプラットフォーム
-
-* アンドロイド
-* iOS
-* Windows Phone 7 と 8
-* Windows
-
-### 簡単な例
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- }
- );
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 seconds
- setTimeout(function() {
- mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### Tizen の癖
-
-* Tizen のデバイスでサポートされていません。
-
-## MediaError
-
-`MediaError` オブジェクトにエラーが発生したときに `mediaError` コールバック関数に返されます。
-
-### プロパティ
-
-* **コード**: 次のいずれかの定義済みのエラー コード。
-
-* **メッセージ**: エラーの詳細を説明するエラー メッセージ。
-
-### 定数
-
-* `MediaError.MEDIA_ERR_ABORTED`= 1
-* `MediaError.MEDIA_ERR_NETWORK`= 2
-* `MediaError.MEDIA_ERR_DECODE`= 3
-* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
diff --git a/doc/ko/README.md b/doc/ko/README.md
deleted file mode 100644
index 811e88eaf..000000000
--- a/doc/ko/README.md
+++ /dev/null
@@ -1,509 +0,0 @@
-
-
-# cordova-plugin-media
-
-[](https://travis-ci.org/apache/cordova-plugin-media)
-
-이 플러그인 기록 장치에 오디오 파일을 재생 하는 기능을 제공 합니다.
-
-**참고**: 현재 구현 미디어 캡처에 대 한 W3C 사양을 준수 하지 않는 및 편의 위해서만 제공 됩니다. 미래 구현 최신 W3C 사양을 준수 한다 고 현재 Api 사용 중지 될 수 있습니다.
-
-이 플러그인은 글로벌 `Media` 생성자를 정의 합니다.
-
-전역 범위에 있지만 그것은 불가능까지 `deviceready` 이벤트 후.
-
- document.addEventListener("deviceready", onDeviceReady, false);
- function onDeviceReady() {
- console.log(Media);
- }
-
-
-## 설치
-
- cordova plugin add cordova-plugin-media
-
-
-## 지원 되는 플랫폼
-
- * 안 드 로이드
- * 블랙베리 10
- * iOS
- * Windows Phone 7과 8
- * Tizen
- * 윈도우 8
- * 윈도우
- * 브라우저
-
-## Windows Phone 단점
-
- * 한 번에 하나의 미디어 파일을 다시 재생할 수 있습니다.
-
- * 응용 프로그램 다른 미디어와 상호 작용 하는 방법에 대 한 엄격한 제한이 있다. [자세한 내용은 Microsoft 문서](http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx) 를 참조 하십시오.
-
-## 미디어
-
- var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### 매개 변수
-
- * **src**: 오디오 콘텐츠를 포함 하는 URI. *(DOMString)*
-
- * **mediaSuccess**: (선택 사항) 후 실행 되는 콜백 한 `Media` 개체 현재 재생, 기록, 또는 중지 작업을 완료 했습니다. *(기능)*
-
- * **mediaError**: (선택 사항) 오류가 발생 하면 실행 되는 콜백. *(기능)*
-
- * **mediaStatus**: (선택 사항) 상태 변화를 나타내기 위해 실행 하는 콜백. *(기능)*
-
-### 상수
-
-다음 상수는 `mediaStatus`를 유일한 매개 변수로 보고 됩니다.
-
- * `Media.MEDIA_NONE` = 0;
- * `Media.MEDIA_STARTING` = 1;
- * `Media.MEDIA_RUNNING` = 2;
- * `Media.MEDIA_PAUSED` = 3;
- * `Media.MEDIA_STOPPED` = 4;
-
-### 메서드
-
- * `media.getCurrentPosition`: 오디오 파일 내에서 현재 위치를 반환합니다.
-
- * `media.getDuration`: 오디오 파일의 기간을 반환합니다.
-
- * `media.play`: 시작 또는 오디오 파일 재생을 다시 시작 합니다.
-
- * `media.pause`: 오디오 파일의 재생을 일시 중지 합니다.
-
- * `media.release`: 기본 운영 체제의 오디오 리소스를 해제합니다.
-
- * `media.seekTo`: 오디오 파일 내에서 위치를 이동합니다.
-
- * `media.setVolume`: 오디오 재생 볼륨을 설정 합니다.
-
- * `media.startRecord`: 오디오 파일을 녹음을 시작 합니다.
-
- * `media.stopRecord`: 오디오 파일 기록을 중지 합니다.
-
- * `media.stop`: 오디오 파일 재생을 중지 합니다.
-
-### 추가 읽기 전용 매개 변수
-
- * **위치**: 위치 오디오 재생 시간 (초).
-
- * 플레이; 하는 동안 자동으로 업데이트 전화 `getCurrentPosition` 를 업데이트 합니다.
-
- * **기간**: 기간, 매체의 초.
-
-## media.getCurrentPosition
-
-오디오 파일 내에서 현재 위치를 반환합니다. 또한 `Media` 개체의 `position` 매개 변수를 업데이트합니다.
-
- media.getCurrentPosition(mediaSuccess, [mediaError]);
-
-
-### 매개 변수
-
- * **mediaSuccess**: 현재 위치 (초) 전달 되는 콜백.
-
- * **mediaError**: (선택 사항) 콜백 실행 오류가 발생 하는 경우에.
-
-### 빠른 예제
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Update media position every second
- var mediaTimer = setInterval(function () {
- // get media position
- my_media.getCurrentPosition(
- // success callback
- function (position) {
- if (position > -1) {
- console.log((position) + " sec");
- }
- },
- // error callback
- function (e) {
- console.log("Error getting pos=" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-초 오디오 파일의 기간을 반환합니다. 기간을 알 수 없는 경우-1 값을 반환 합니다.
-
- media.getDuration();
-
-
-### 빠른 예제
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(function() {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = my_media.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + " sec";
- }
- }, 100);
-
-
-## media.pause
-
-오디오 파일 재생을 일시 중지 합니다.
-
- media.pause();
-
-
-### 빠른 예제
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () { console.log("playAudio():Audio Success"); },
- // error callback
- function (err) { console.log("playAudio():Audio Error: " + err); }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function () {
- media.pause();
- }, 10000);
- }
-
-
-## media.play
-
-시작 또는 오디오 파일 재생을 다시 시작 합니다.
-
- media.play();
-
-
-### 빠른 예제
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function (err) {
- console.log("playAudio():Audio Error: " + err);
- }
- );
- // Play audio
- my_media.play();
- }
-
-
-### iOS 단점
-
- * **numberOfLoops**:이 옵션을 전달할는 `play` 시간을 재생 하려면, 예를 들어 미디어 파일의 수를 지정 하는 방법:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
- * **playAudioWhenScreenIsLocked**:이 옵션을 전달할는 `play` 메서드는 화면이 잠겨 때 재생 수 있도록 지정 하려면. 만약 설정 `true` (기본값) 하드웨어 음소거 버튼의 상태, 예를 들면 무시 됩니다:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
- * **파일 검색의 순서**: iOS에서 검색 한 파일 이름 또는 간단한 경로 제공 하는 경우는 `www` 파일을 다음 응용 프로그램의 디렉터리 `documents/tmp` 디렉터리:
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-기본 운영 체제의 오디오 리소스를 해제합니다. 이것은 유한 양의 미디어 재생용 OpenCore 인스턴스 때문에 안 드 로이드를 위해 특히 중요 하다입니다. 응용 프로그램은 더 이상 필요 없는 모든 `Media` 리소스에 대 한 `release` 함수를 호출 해야 합니다.
-
- media.release();
-
-
-### 빠른 예제
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- my_media.play();
- my_media.stop();
- my_media.release();
-
-
-## media.seekTo
-
-오디오 파일 내의 현재 위치를 설정합니다.
-
- media.seekTo(milliseconds);
-
-
-### 매개 변수
-
- * **밀리초**: 밀리초에서는 오디오에서 재생 위치를 설정 하는 위치.
-
-### 빠른 예제
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
- my_media.play();
- // SeekTo to 10 seconds after 5 seconds
- setTimeout(function() {
- my_media.seekTo(10000);
- }, 5000);
-
-
-### 블랙베리 10 단점
-
- * 블랙베리 OS 5 장치에서 지원 되지 않습니다.
-
-## media.setVolume
-
-오디오 파일의 볼륨을 설정 합니다.
-
- media.setVolume(volume);
-
-
-### 매개 변수
-
- * **볼륨**: 볼륨 재생을 위한 설정. 값은 0.0에서 1.0의 범위 내에서 해야 합니다.
-
-### 지원 되는 플랫폼
-
- * 안 드 로이드
- * iOS
-
-### 빠른 예제
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- });
-
- // Play audio
- my_media.play();
-
- // Mute volume after 2 seconds
- setTimeout(function() {
- my_media.setVolume('0.0');
- }, 2000);
-
- // Set volume to 1.0 after 5 seconds
- setTimeout(function() {
- my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-오디오 파일 녹음을 시작 합니다.
-
- media.startRecord();
-
-
-### 지원 되는 플랫폼
-
- * 안 드 로이드
- * iOS
- * Windows Phone 7과 8
- * 윈도우
-
-### 빠른 예제
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- });
-
- // Record audio
- mediaRec.startRecord();
- }
-
-
-### 안 드 로이드 단점
-
- * 안 드 로이드 장치 적응 다중 속도 형식에서 오디오를 기록합니다. 지정 된 파일 *.amr* 확장명으로 끝나야 합니다.
- * 하드웨어 볼륨 제어는 어떤 미디어 객체 살아 있는 동안 미디어 볼륨까지 유선. 일단 개체는 `release()` 호출 마지막 만든된 미디어 볼륨 컨트롤 그들의 기본 동작을 되돌립니다. 컨트롤은 또한 원래 대로 페이지 네비게이션이 모든 매체 개체를 출시.
-
-### iOS 단점
-
- * iOS만 레코드 형식을 *.wav* 및 반환 오류 경우 파일 이름 확장명의 파일을 수정 하지.
-
- * 전체 경로 제공 하지 않으면 응용 프로그램의 기록 배치 됩니다 `documents/tmp` 디렉터리. 이 통해 액세스할 수 있는 `File` API를 사용 하 여 `LocalFileSystem.TEMPORARY` . 기록 시간에 지정 된 하위 디렉터리에 이미 존재 해야 합니다.
-
- * 파일을 기록 하 고 재생할 수 있습니다 문서 URI를 사용 하 여 다시:
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### 윈도우 특수
-
- * Windows 장치 MP3, M4A를 사용할 수 있고 WMA 형식 오디오 기록. 그러나 대부분의 경우에서 불가능 MP3 인코더는 [Windows Phone 포함 되지](https://msdn.microsoft.com/en-us/library/windows/apps/windows.media.mediaproperties.mediaencodingprofile.createmp3.aspx) 때문에 *Windows Phone 8.1* 장치에서 오디오 녹음에 대 한 m p 3를 사용 하 여.
-
- * 전체 경로 제공 하지 않으면 녹음 AppData/temp 디렉터리에 배치 됩니다. 이 통해 액세스할 수 있는 `파일` API를 사용 하 여 `LocalFileSystem.TEMPORARY` 또는 ' ms appdata: 온도 / / / /' URI.
-
- * 기록 시간에 지정 된 하위 디렉터리에 이미 존재 해야 합니다.
-
-### Tizen 특수
-
- * Tizen 장치에서 지원 되지 않습니다.
-
-## media.stop
-
-오디오 파일 재생을 중지 합니다.
-
- media.stop();
-
-
-### 빠른 예제
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function() {
- my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-오디오 파일 녹음을 중지 합니다.
-
- media.stopRecord();
-
-
-### 지원 되는 플랫폼
-
- * 안 드 로이드
- * iOS
- * Windows Phone 7과 8
- * 윈도우
-
-### 빠른 예제
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- }
- );
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 seconds
- setTimeout(function() {
- mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### Tizen 특수
-
- * Tizen 장치에서 지원 되지 않습니다.
-
-## MediaError
-
-`MediaError` 개체는 오류가 발생 하면 `mediaError` 콜백 함수에 반환 됩니다.
-
-### 속성
-
- * **코드**: 미리 정의 된 오류 코드 중 하나가 아래에 나열 된.
-
- * **메시지**: 오류 세부 정보를 설명 하는 오류 메시지.
-
-### 상수
-
- * `MediaError.MEDIA_ERR_ABORTED`= 1
- * `MediaError.MEDIA_ERR_NETWORK`= 2
- * `MediaError.MEDIA_ERR_DECODE`= 3
- * `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file
diff --git a/doc/ko/index.md b/doc/ko/index.md
deleted file mode 100644
index d43477a54..000000000
--- a/doc/ko/index.md
+++ /dev/null
@@ -1,505 +0,0 @@
-
-
-# cordova-plugin-media
-
-이 플러그인 기록 장치에 오디오 파일을 재생 하는 기능을 제공 합니다.
-
-**참고**: 현재 구현 미디어 캡처에 대 한 W3C 사양을 준수 하지 않는 및 편의 위해서만 제공 됩니다. 미래 구현 최신 W3C 사양을 준수 한다 고 현재 Api 사용 중지 될 수 있습니다.
-
-이 플러그인은 글로벌 `Media` 생성자를 정의 합니다.
-
-전역 범위에 있지만 그것은 불가능까지 `deviceready` 이벤트 후.
-
- document.addEventListener("deviceready", onDeviceReady, false);
- function onDeviceReady() {
- console.log(Media);
- }
-
-
-## 설치
-
- cordova plugin add cordova-plugin-media
-
-
-## 지원 되는 플랫폼
-
-* 안 드 로이드
-* 블랙베리 10
-* iOS
-* Windows Phone 7과 8
-* Tizen
-* 윈도우
-
-## Windows Phone 단점
-
-* 한 번에 하나의 미디어 파일을 다시 재생할 수 있습니다.
-
-* 응용 프로그램 다른 미디어와 상호 작용 하는 방법에 대 한 엄격한 제한이 있다. [자세한 내용은 Microsoft 문서][1] 를 참조 하십시오.
-
- [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx
-
-## 미디어
-
- var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### 매개 변수
-
-* **src**: 오디오 콘텐츠를 포함 하는 URI. *(DOMString)*
-
-* **mediaSuccess**: (선택 사항) 후 실행 되는 콜백 한 `Media` 개체 현재 재생, 기록, 또는 중지 작업을 완료 했습니다. *(기능)*
-
-* **mediaError**: (선택 사항) 오류가 발생 하면 실행 되는 콜백. *(기능)*
-
-* **mediaStatus**: (선택 사항) 상태 변화를 나타내기 위해 실행 하는 콜백. *(기능)*
-
-### 상수
-
-다음 상수는 `mediaStatus`를 유일한 매개 변수로 보고 됩니다.
-
-* `Media.MEDIA_NONE` = 0;
-* `Media.MEDIA_STARTING` = 1;
-* `Media.MEDIA_RUNNING` = 2;
-* `Media.MEDIA_PAUSED` = 3;
-* `Media.MEDIA_STOPPED` = 4;
-
-### 메서드
-
-* `media.getCurrentPosition`: 오디오 파일 내에서 현재 위치를 반환합니다.
-
-* `media.getDuration`: 오디오 파일의 기간을 반환합니다.
-
-* `media.play`: 시작 또는 오디오 파일 재생을 다시 시작 합니다.
-
-* `media.pause`: 오디오 파일의 재생을 일시 중지 합니다.
-
-* `media.release`: 기본 운영 체제의 오디오 리소스를 해제합니다.
-
-* `media.seekTo`: 오디오 파일 내에서 위치를 이동합니다.
-
-* `media.setVolume`: 오디오 재생 볼륨을 설정 합니다.
-
-* `media.startRecord`: 오디오 파일을 녹음을 시작 합니다.
-
-* `media.stopRecord`: 오디오 파일 기록을 중지 합니다.
-
-* `media.stop`: 오디오 파일 재생을 중지 합니다.
-
-### 추가 읽기 전용 매개 변수
-
-* **위치**: 위치 오디오 재생 시간 (초).
-
- * 플레이; 하는 동안 자동으로 업데이트 전화 `getCurrentPosition` 를 업데이트 합니다.
-
-* **기간**: 기간, 매체의 초.
-
-## media.getCurrentPosition
-
-오디오 파일 내에서 현재 위치를 반환합니다. 또한 `Media` 개체의 `position` 매개 변수를 업데이트합니다.
-
- media.getCurrentPosition(mediaSuccess, [mediaError]);
-
-
-### 매개 변수
-
-* **mediaSuccess**: 현재 위치 (초) 전달 되는 콜백.
-
-* **mediaError**: (선택 사항) 콜백 실행 오류가 발생 하는 경우에.
-
-### 빠른 예제
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Update media position every second
- var mediaTimer = setInterval(function () {
- // get media position
- my_media.getCurrentPosition(
- // success callback
- function (position) {
- if (position > -1) {
- console.log((position) + " sec");
- }
- },
- // error callback
- function (e) {
- console.log("Error getting pos=" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-초 오디오 파일의 기간을 반환합니다. 기간을 알 수 없는 경우-1 값을 반환 합니다.
-
- media.getDuration();
-
-
-### 빠른 예제
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(function() {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = my_media.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + " sec";
- }
- }, 100);
-
-
-## media.pause
-
-오디오 파일 재생을 일시 중지 합니다.
-
- media.pause();
-
-
-### 빠른 예제
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () { console.log("playAudio():Audio Success"); },
- // error callback
- function (err) { console.log("playAudio():Audio Error: " + err); }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function () {
- media.pause();
- }, 10000);
- }
-
-
-## media.play
-
-시작 또는 오디오 파일 재생을 다시 시작 합니다.
-
- media.play();
-
-
-### 빠른 예제
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function (err) {
- console.log("playAudio():Audio Error: " + err);
- }
- );
- // Play audio
- my_media.play();
- }
-
-
-### iOS 단점
-
-* **numberOfLoops**:이 옵션을 전달할는 `play` 시간을 재생 하려면, 예를 들어 미디어 파일의 수를 지정 하는 방법:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
-* **playAudioWhenScreenIsLocked**:이 옵션을 전달할는 `play` 메서드는 화면이 잠겨 때 재생 수 있도록 지정 하려면. 만약 설정 `true` (기본값) 하드웨어 음소거 버튼의 상태, 예를 들면 무시 됩니다:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
-* **파일 검색의 순서**: iOS에서 검색 한 파일 이름 또는 간단한 경로 제공 하는 경우는 `www` 파일을 다음 응용 프로그램의 디렉터리 `documents/tmp` 디렉터리:
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-기본 운영 체제의 오디오 리소스를 해제합니다. 이것은 유한 양의 미디어 재생용 OpenCore 인스턴스 때문에 안 드 로이드를 위해 특히 중요 하다입니다. 응용 프로그램은 더 이상 필요 없는 모든 `Media` 리소스에 대 한 `release` 함수를 호출 해야 합니다.
-
- media.release();
-
-
-### 빠른 예제
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- my_media.play();
- my_media.stop();
- my_media.release();
-
-
-## media.seekTo
-
-오디오 파일 내의 현재 위치를 설정합니다.
-
- media.seekTo(milliseconds);
-
-
-### 매개 변수
-
-* **밀리초**: 밀리초에서는 오디오에서 재생 위치를 설정 하는 위치.
-
-### 빠른 예제
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
- my_media.play();
- // SeekTo to 10 seconds after 5 seconds
- setTimeout(function() {
- my_media.seekTo(10000);
- }, 5000);
-
-
-### 블랙베리 10 단점
-
-* 블랙베리 OS 5 장치에서 지원 되지 않습니다.
-
-## media.setVolume
-
-오디오 파일의 볼륨을 설정 합니다.
-
- media.setVolume(volume);
-
-
-### 매개 변수
-
-* **볼륨**: 볼륨 재생을 위한 설정. 값은 0.0에서 1.0의 범위 내에서 해야 합니다.
-
-### 지원 되는 플랫폼
-
-* 안 드 로이드
-* iOS
-
-### 빠른 예제
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- });
-
- // Play audio
- my_media.play();
-
- // Mute volume after 2 seconds
- setTimeout(function() {
- my_media.setVolume('0.0');
- }, 2000);
-
- // Set volume to 1.0 after 5 seconds
- setTimeout(function() {
- my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-오디오 파일 녹음을 시작 합니다.
-
- media.startRecord();
-
-
-### 지원 되는 플랫폼
-
-* 안 드 로이드
-* iOS
-* Windows Phone 7과 8
-* 윈도우
-
-### 빠른 예제
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- });
-
- // Record audio
- mediaRec.startRecord();
- }
-
-
-### 안 드 로이드 단점
-
-* 안 드 로이드 장치 적응 다중 속도 형식에서 오디오를 기록합니다. 지정 된 파일 *.amr* 확장명으로 끝나야 합니다.
-* 하드웨어 볼륨 제어는 어떤 미디어 객체 살아 있는 동안 미디어 볼륨까지 유선. 일단 개체는 `release()` 호출 마지막 만든된 미디어 볼륨 컨트롤 그들의 기본 동작을 되돌립니다. 컨트롤은 또한 원래 대로 페이지 네비게이션이 모든 매체 개체를 출시.
-
-### iOS 단점
-
-* iOS만 레코드 형식을 *.wav* 및 반환 오류 경우 파일 이름 확장명의 파일을 수정 하지.
-
-* 전체 경로 제공 하지 않으면 응용 프로그램의 기록 배치 됩니다 `documents/tmp` 디렉터리. 이 통해 액세스할 수 있는 `File` API를 사용 하 여 `LocalFileSystem.TEMPORARY` . 기록 시간에 지정 된 하위 디렉터리에 이미 존재 해야 합니다.
-
-* 파일을 기록 하 고 재생할 수 있습니다 문서 URI를 사용 하 여 다시:
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### 윈도우 특수
-
-* 전체 경로 제공 하지 않으면 녹음 AppData/temp 디렉터리에 배치 됩니다. 이 통해 액세스할 수 있는 `파일` API를 사용 하 여 `LocalFileSystem.TEMPORARY` 또는 ' ms appdata: 온도 / / / /' URI.
-
-* 기록 시간에 지정 된 하위 디렉터리에 이미 존재 해야 합니다.
-
-### Tizen 특수
-
-* Tizen 장치에서 지원 되지 않습니다.
-
-## media.stop
-
-오디오 파일 재생을 중지 합니다.
-
- media.stop();
-
-
-### 빠른 예제
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function() {
- my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-오디오 파일 녹음을 중지 합니다.
-
- media.stopRecord();
-
-
-### 지원 되는 플랫폼
-
-* 안 드 로이드
-* iOS
-* Windows Phone 7과 8
-* 윈도우
-
-### 빠른 예제
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- }
- );
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 seconds
- setTimeout(function() {
- mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### Tizen 특수
-
-* Tizen 장치에서 지원 되지 않습니다.
-
-## MediaError
-
-`MediaError` 개체는 오류가 발생 하면 `mediaError` 콜백 함수에 반환 됩니다.
-
-### 속성
-
-* **코드**: 미리 정의 된 오류 코드 중 하나가 아래에 나열 된.
-
-* **메시지**: 오류 세부 정보를 설명 하는 오류 메시지.
-
-### 상수
-
-* `MediaError.MEDIA_ERR_ABORTED`= 1
-* `MediaError.MEDIA_ERR_NETWORK`= 2
-* `MediaError.MEDIA_ERR_DECODE`= 3
-* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
diff --git a/doc/pl/README.md b/doc/pl/README.md
deleted file mode 100644
index 2c3cbabb8..000000000
--- a/doc/pl/README.md
+++ /dev/null
@@ -1,509 +0,0 @@
-
-
-# cordova-plugin-media
-
-[](https://travis-ci.org/apache/cordova-plugin-media)
-
-Plugin daje możliwość nagrywania i odtwarzania plików audio na urządzeniu.
-
-**Uwaga**: Obecna implementacja nie stosować się do specyfikacji W3C do przechwytywania mediów i jest dostarczane jedynie dla wygody. Przyszłej realizacji będą przylegać do najnowszych specyfikacji W3C i może potępiać bieżące interfejsów API.
-
-Ten plugin definiuje globalny Konstruktor `Media`.
-
-Chociaż w globalnym zasięgu, to nie dostępne dopiero po `deviceready` imprezie.
-
- document.addEventListener("deviceready", onDeviceReady, false);
- function onDeviceReady() {
- console.log(Media);
- }
-
-
-## Instalacja
-
- cordova plugin add cordova-plugin-media
-
-
-## Obsługiwane platformy
-
- * Android
- * BlackBerry 10
- * iOS
- * Windows Phone 7 i 8
- * Tizen
- * Windows 8
- * Windows
- * Przeglądarka
-
-## Windows Phone dziwactwa
-
- * Tylko jeden plik mogą być zagrany w tył w czasie.
-
- * Istnieją ścisłe ograniczenia na jak aplikacja współdziała z innymi mediami. Zobacz [Microsoft dokumentacji szczegóły](http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx).
-
-## Media
-
- var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### Parametry
-
- * **src**: URI zawierający zawartość audio. *(DOMString)*
-
- * **mediaSuccess**: (opcjonalne) wywołania zwrotnego, który wykonuje po `Media` obiektu została zakończona bieżącej gry, rekordu lub działania stop. *(Funkcja)*
-
- * **mediaError**: (opcjonalne) wywołania zwrotnego, która wykonuje w przypadku wystąpienia błędu. *(Funkcja)*
-
- * **mediaStatus**: (opcjonalne) wywołania zwrotnego, który wykonuje wskazać zmiany statusu. *(Funkcja)*
-
-### Stałe
-
-Poniższe stałe są zgłaszane jako parametr tylko do wywołania zwrotnego `mediaStatus`:
-
- * `Media.MEDIA_NONE`= 0;
- * `Media.MEDIA_STARTING`= 1;
- * `Media.MEDIA_RUNNING`= 2;
- * `Media.MEDIA_PAUSED`= 3;
- * `Media.MEDIA_STOPPED`= 4;
-
-### Metody
-
- * `media.getCurrentPosition`: Zwraca bieżącej pozycji w pliku audio.
-
- * `media.getDuration`: Zwraca czas trwania pliku audio.
-
- * `media.play`: Rozpoczęcie lub wznowienie odtwarzania pliku audio.
-
- * `media.pause`: Wstrzymanie odtwarzania pliku audio.
-
- * `media.release`: Zwalnia zasoby audio system operacyjny.
-
- * `media.seekTo`: Porusza się pozycji w pliku audio.
-
- * `media.setVolume`: Ustaw głośność odtwarzania dźwięku.
-
- * `media.startRecord`: Nagrywanie pliku audio.
-
- * `media.stopRecord`: Zatrzymaj nagrywanie pliku audio.
-
- * `media.stop`: Zatrzymania odtwarzania pliku audio.
-
-### Parametry dodatkowe ReadOnly
-
- * **stanowisko**: stanowisko w odtwarzaniu dźwięku, w kilka sekund.
-
- * Nie jest automatycznie aktualizowana podczas odtwarzania; wywołanie `getCurrentPosition` aktualizacji.
-
- * **czas**: trwania mediów, w kilka sekund.
-
-## media.getCurrentPosition
-
-Zwraca bieżącą pozycję w pliku audio. Również aktualizacje obiektu `Media` `Position` parametr.
-
- media.getCurrentPosition(mediaSuccess, [mediaError]);
-
-
-### Parametry
-
- * **mediaSuccess**: wywołania zwrotnego, który jest przekazywany bieżącej pozycji w kilka sekund.
-
- * **mediaError**: (opcjonalne) wywołanie zwrotne do wykonać, jeśli wystąpi błąd.
-
-### Szybki przykład
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Update media position every second
- var mediaTimer = setInterval(function () {
- // get media position
- my_media.getCurrentPosition(
- // success callback
- function (position) {
- if (position > -1) {
- console.log((position) + " sec");
- }
- },
- // error callback
- function (e) {
- console.log("Error getting pos=" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-Zwraca czas trwania pliku audio w kilka sekund. Jeśli czas trwania jest nieznane, to zwraca wartość -1.
-
- media.getDuration();
-
-
-### Szybki przykład
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(function() {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = my_media.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + " sec";
- }
- }, 100);
-
-
-## Media.Pause
-
-Wstrzymuje odtwarzanie pliku audio.
-
- media.pause();
-
-
-### Szybki przykład
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () { console.log("playAudio():Audio Success"); },
- // error callback
- function (err) { console.log("playAudio():Audio Error: " + err); }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function () {
- media.pause();
- }, 10000);
- }
-
-
-## Media.play
-
-Rozpoczyna się lub wznawia odtwarzanie pliku audio.
-
- media.play();
-
-
-### Szybki przykład
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function (err) {
- console.log("playAudio():Audio Error: " + err);
- }
- );
- // Play audio
- my_media.play();
- }
-
-
-### Dziwactwa iOS
-
- * **numberOfLoops**: przekazać tę opcję, aby `play` Metoda, aby określić ile razy chcesz, pliku multimedialnego do gry, np.:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
- * **playAudioWhenScreenIsLocked**: przekazać tę opcję, aby `play` Metoda, aby określić, czy chcesz umożliwić odtwarzanie, gdy ekran jest zablokowana. Jeśli zestaw `true` (wartość domyślna), stan przycisku Wycisz sprzętu jest ignorowane, np.:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
- * **kolejność wyszukiwania plików**: gdy tylko nazwa pliku lub ścieżka prosta pod warunkiem, iOS wyszukiwania w `www` katalogu, pliku, a następnie w aplikacji `documents/tmp` katalogu:
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-Zwalnia zasoby audio system operacyjny. Jest to szczególnie ważne dla systemu Android, ponieważ istnieje skończona ilość podstawie OpenCore wystąpień do odtwarzania multimediów. Aplikacje powinny wywoływać funkcję `wydania` dla wszelkich zasobów `mediów`, że nie jest już potrzebna.
-
- media.release();
-
-
-### Szybki przykład
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- my_media.play();
- my_media.stop();
- my_media.release();
-
-
-## media.seekTo
-
-Ustawia bieżącej pozycji w pliku audio.
-
- media.seekTo(milliseconds);
-
-
-### Parametry
-
- * **milisekund**: stanowisko ustala pozycję odtwarzania w audio, w milisekundach.
-
-### Szybki przykład
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
- my_media.play();
- // SeekTo to 10 seconds after 5 seconds
- setTimeout(function() {
- my_media.seekTo(10000);
- }, 5000);
-
-
-### Jeżyna 10 dziwactwa
-
- * Nie obsługiwane na urządzeniach BlackBerry OS w wersji 5.
-
-## media.setVolume
-
-Ustaw głośność pliku audio.
-
- media.setVolume(volume);
-
-
-### Parametry
-
- * **wielkość**: wielkość ustawić odtwarzanie. Wartość musi być z zakresu od 0.0 do 1.0.
-
-### Obsługiwane platformy
-
- * Android
- * iOS
-
-### Szybki przykład
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- });
-
- // Play audio
- my_media.play();
-
- // Mute volume after 2 seconds
- setTimeout(function() {
- my_media.setVolume('0.0');
- }, 2000);
-
- // Set volume to 1.0 after 5 seconds
- setTimeout(function() {
- my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-Rozpoczyna nagrywanie pliku audio.
-
- media.startRecord();
-
-
-### Obsługiwane platformy
-
- * Android
- * iOS
- * Windows Phone 7 i 8
- * Windows
-
-### Szybki przykład
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- });
-
- // Record audio
- mediaRec.startRecord();
- }
-
-
-### Dziwactwa Androida
-
- * Urządzenia z systemem Android nagrywanie dźwięku w formacie Adaptive Multi-Rate. Określony plik powinien kończyć się rozszerzeniem *AMR* .
- * Głośności sprzętu są okablowane do wielkości nośnika, a wszelkie obiekty multimedialne są żywe. Po raz ostatni Media utworzony obiekt ma `release()` wezwał go, głośności przywrócić ich domyślne zachowanie. Kontrole są również reset nawigacji strony, jak to wszystkie obiekty multimedialne.
-
-### Dziwactwa iOS
-
- * iOS tylko rekordy do plików typu *.wav* i zwraca błąd, jeśli nazwa pliku rozszerzenie jest nie prawidłowe.
-
- * Jeśli nie podano pełną ścieżkę, nagrywanie jest umieszczony w aplikacji `documents/tmp` katalogu. To mogą być dostępne za pośrednictwem `File` za pomocą interfejsu API `LocalFileSystem.TEMPORARY` . Każdy podkatalog określony w rekordowym czasie musi już istnieć.
-
- * Pliki mogą być zapisywane i grał z powrotem za pomocą dokumentów URI:
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Windows dziwactwa
-
- * Urządzenia systemu Windows może używać MP3, M4A i formaty WMA rejestrowane audio. Jednak w większości przypadków nie jest możliwe wykorzystanie MP3 do nagrywania dźwięku na urządzenia *Windows Phone 8.1* , ponieważ jest enkoder MP3 [nie wysłane z Windows Phone](https://msdn.microsoft.com/en-us/library/windows/apps/windows.media.mediaproperties.mediaencodingprofile.createmp3.aspx).
-
- * Jeśli nie podano pełną ścieżkę, nagrywanie jest umieszczony w katalogu AppData/temp. To mogą być dostępne za pośrednictwem `Plik` Za pomocą interfejsu API `LocalFileSystem.TEMPORARY` lub "ms-appdata: temp / / / /"URI.
-
- * Każdy podkatalog określony w rekordowym czasie musi już istnieć.
-
-### Dziwactwa Tizen
-
- * Nie obsługiwane na Tizen urządzenia.
-
-## media.stop
-
-Zatrzymuje odtwarzanie pliku audio.
-
- media.stop();
-
-
-### Szybki przykład
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function() {
- my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-Zatrzymuje nagrywanie pliku audio.
-
- media.stopRecord();
-
-
-### Obsługiwane platformy
-
- * Android
- * iOS
- * Windows Phone 7 i 8
- * Windows
-
-### Szybki przykład
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- }
- );
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 seconds
- setTimeout(function() {
- mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### Dziwactwa Tizen
-
- * Nie obsługiwane na Tizen urządzenia.
-
-## MediaError
-
-Gdy wystąpi błąd, funkcja wywołania zwrotnego `mediaError` zwracany jest obiekt `MediaError`.
-
-### Właściwości
-
- * **Kod**: jeden z kodów błędów wstępnie zdefiniowanych poniżej.
-
- * **wiadomość**: komunikat o błędzie, opisując szczegóły błędu.
-
-### Stałe
-
- * `MediaError.MEDIA_ERR_ABORTED`= 1
- * `MediaError.MEDIA_ERR_NETWORK`= 2
- * `MediaError.MEDIA_ERR_DECODE`= 3
- * `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file
diff --git a/doc/pl/index.md b/doc/pl/index.md
deleted file mode 100644
index 5088bb3bf..000000000
--- a/doc/pl/index.md
+++ /dev/null
@@ -1,505 +0,0 @@
-
-
-# cordova-plugin-media
-
-Plugin daje możliwość nagrywania i odtwarzania plików audio na urządzeniu.
-
-**Uwaga**: Obecna implementacja nie stosować się do specyfikacji W3C do przechwytywania mediów i jest dostarczane jedynie dla wygody. Przyszłej realizacji będą przylegać do najnowszych specyfikacji W3C i może potępiać bieżące interfejsów API.
-
-Ten plugin definiuje globalny Konstruktor `Media`.
-
-Chociaż w globalnym zasięgu, to nie dostępne dopiero po `deviceready` imprezie.
-
- document.addEventListener("deviceready", onDeviceReady, false);
- function onDeviceReady() {
- console.log(Media);
- }
-
-
-## Instalacja
-
- cordova plugin add cordova-plugin-media
-
-
-## Obsługiwane platformy
-
-* Android
-* BlackBerry 10
-* iOS
-* Windows Phone 7 i 8
-* Tizen
-* Windows
-
-## Windows Phone dziwactwa
-
-* Tylko jeden plik mogą być zagrany w tył w czasie.
-
-* Istnieją ścisłe ograniczenia na jak aplikacja współdziała z innymi mediami. Zobacz [Microsoft dokumentacji szczegóły][1].
-
- [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx
-
-## Media
-
- var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### Parametry
-
-* **src**: URI zawierający zawartość audio. *(DOMString)*
-
-* **mediaSuccess**: (opcjonalne) wywołania zwrotnego, który wykonuje po `Media` obiektu została zakończona bieżącej gry, rekordu lub działania stop. *(Funkcja)*
-
-* **mediaError**: (opcjonalne) wywołania zwrotnego, która wykonuje w przypadku wystąpienia błędu. *(Funkcja)*
-
-* **mediaStatus**: (opcjonalne) wywołania zwrotnego, który wykonuje wskazać zmiany statusu. *(Funkcja)*
-
-### Stałe
-
-Poniższe stałe są zgłaszane jako parametr tylko do wywołania zwrotnego `mediaStatus`:
-
-* `Media.MEDIA_NONE`= 0;
-* `Media.MEDIA_STARTING`= 1;
-* `Media.MEDIA_RUNNING`= 2;
-* `Media.MEDIA_PAUSED`= 3;
-* `Media.MEDIA_STOPPED`= 4;
-
-### Metody
-
-* `media.getCurrentPosition`: Zwraca bieżącej pozycji w pliku audio.
-
-* `media.getDuration`: Zwraca czas trwania pliku audio.
-
-* `media.play`: Rozpoczęcie lub wznowienie odtwarzania pliku audio.
-
-* `media.pause`: Wstrzymanie odtwarzania pliku audio.
-
-* `media.release`: Zwalnia zasoby audio system operacyjny.
-
-* `media.seekTo`: Porusza się pozycji w pliku audio.
-
-* `media.setVolume`: Ustaw głośność odtwarzania dźwięku.
-
-* `media.startRecord`: Nagrywanie pliku audio.
-
-* `media.stopRecord`: Zatrzymaj nagrywanie pliku audio.
-
-* `media.stop`: Zatrzymania odtwarzania pliku audio.
-
-### Parametry dodatkowe ReadOnly
-
-* **stanowisko**: stanowisko w odtwarzaniu dźwięku, w kilka sekund.
-
- * Nie jest automatycznie aktualizowana podczas odtwarzania; wywołanie `getCurrentPosition` aktualizacji.
-
-* **czas**: trwania mediów, w kilka sekund.
-
-## media.getCurrentPosition
-
-Zwraca bieżącą pozycję w pliku audio. Również aktualizacje obiektu `Media` `Position` parametr.
-
- media.getCurrentPosition(mediaSuccess, [mediaError]);
-
-
-### Parametry
-
-* **mediaSuccess**: wywołania zwrotnego, który jest przekazywany bieżącej pozycji w kilka sekund.
-
-* **mediaError**: (opcjonalne) wywołanie zwrotne do wykonać, jeśli wystąpi błąd.
-
-### Szybki przykład
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Update media position every second
- var mediaTimer = setInterval(function () {
- // get media position
- my_media.getCurrentPosition(
- // success callback
- function (position) {
- if (position > -1) {
- console.log((position) + " sec");
- }
- },
- // error callback
- function (e) {
- console.log("Error getting pos=" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-Zwraca czas trwania pliku audio w kilka sekund. Jeśli czas trwania jest nieznane, to zwraca wartość -1.
-
- media.getDuration();
-
-
-### Szybki przykład
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(function() {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = my_media.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + " sec";
- }
- }, 100);
-
-
-## Media.Pause
-
-Wstrzymuje odtwarzanie pliku audio.
-
- media.pause();
-
-
-### Szybki przykład
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () { console.log("playAudio():Audio Success"); },
- // error callback
- function (err) { console.log("playAudio():Audio Error: " + err); }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function () {
- media.pause();
- }, 10000);
- }
-
-
-## Media.play
-
-Rozpoczyna się lub wznawia odtwarzanie pliku audio.
-
- media.play();
-
-
-### Szybki przykład
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function (err) {
- console.log("playAudio():Audio Error: " + err);
- }
- );
- // Play audio
- my_media.play();
- }
-
-
-### Dziwactwa iOS
-
-* **numberOfLoops**: przekazać tę opcję, aby `play` Metoda, aby określić ile razy chcesz, pliku multimedialnego do gry, np.:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
-* **playAudioWhenScreenIsLocked**: przekazać tę opcję, aby `play` Metoda, aby określić, czy chcesz umożliwić odtwarzanie, gdy ekran jest zablokowana. Jeśli zestaw `true` (wartość domyślna), stan przycisku Wycisz sprzętu jest ignorowane, np.:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
-* **kolejność wyszukiwania plików**: gdy tylko nazwa pliku lub ścieżka prosta pod warunkiem, iOS wyszukiwania w `www` katalogu, pliku, a następnie w aplikacji `documents/tmp` katalogu:
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-Zwalnia zasoby audio system operacyjny. Jest to szczególnie ważne dla systemu Android, ponieważ istnieje skończona ilość podstawie OpenCore wystąpień do odtwarzania multimediów. Aplikacje powinny wywoływać funkcję `wydania` dla wszelkich zasobów `mediów`, że nie jest już potrzebna.
-
- media.release();
-
-
-### Szybki przykład
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- my_media.play();
- my_media.stop();
- my_media.release();
-
-
-## media.seekTo
-
-Ustawia bieżącej pozycji w pliku audio.
-
- media.seekTo(milliseconds);
-
-
-### Parametry
-
-* **milisekund**: stanowisko ustala pozycję odtwarzania w audio, w milisekundach.
-
-### Szybki przykład
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
- my_media.play();
- // SeekTo to 10 seconds after 5 seconds
- setTimeout(function() {
- my_media.seekTo(10000);
- }, 5000);
-
-
-### Jeżyna 10 dziwactwa
-
-* Nie obsługiwane na urządzeniach BlackBerry OS w wersji 5.
-
-## media.setVolume
-
-Ustaw głośność pliku audio.
-
- media.setVolume(volume);
-
-
-### Parametry
-
-* **wielkość**: wielkość ustawić odtwarzanie. Wartość musi być z zakresu od 0.0 do 1.0.
-
-### Obsługiwane platformy
-
-* Android
-* iOS
-
-### Szybki przykład
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- });
-
- // Play audio
- my_media.play();
-
- // Mute volume after 2 seconds
- setTimeout(function() {
- my_media.setVolume('0.0');
- }, 2000);
-
- // Set volume to 1.0 after 5 seconds
- setTimeout(function() {
- my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-Rozpoczyna nagrywanie pliku audio.
-
- media.startRecord();
-
-
-### Obsługiwane platformy
-
-* Android
-* iOS
-* Windows Phone 7 i 8
-* Windows
-
-### Szybki przykład
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- });
-
- // Record audio
- mediaRec.startRecord();
- }
-
-
-### Dziwactwa Androida
-
-* Urządzenia z systemem Android nagrywanie dźwięku w formacie Adaptive Multi-Rate. Określony plik powinien kończyć się rozszerzeniem *AMR* .
-* Głośności sprzętu są okablowane do wielkości nośnika, a wszelkie obiekty multimedialne są żywe. Po raz ostatni Media utworzony obiekt ma `release()` wezwał go, głośności przywrócić ich domyślne zachowanie. Kontrole są również reset nawigacji strony, jak to wszystkie obiekty multimedialne.
-
-### Dziwactwa iOS
-
-* iOS tylko rekordy do plików typu *.wav* i zwraca błąd, jeśli nazwa pliku rozszerzenie jest nie prawidłowe.
-
-* Jeśli nie podano pełną ścieżkę, nagrywanie jest umieszczony w aplikacji `documents/tmp` katalogu. To mogą być dostępne za pośrednictwem `File` za pomocą interfejsu API `LocalFileSystem.TEMPORARY` . Każdy podkatalog określony w rekordowym czasie musi już istnieć.
-
-* Pliki mogą być zapisywane i grał z powrotem za pomocą dokumentów URI:
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Windows dziwactwa
-
-* Jeśli nie podano pełną ścieżkę, nagrywanie jest umieszczony w katalogu AppData/temp. To mogą być dostępne za pośrednictwem `Plik` Za pomocą interfejsu API `LocalFileSystem.TEMPORARY` lub "ms-appdata: temp / / / /"URI.
-
-* Każdy podkatalog określony w rekordowym czasie musi już istnieć.
-
-### Dziwactwa Tizen
-
-* Nie obsługiwane na Tizen urządzenia.
-
-## media.stop
-
-Zatrzymuje odtwarzanie pliku audio.
-
- media.stop();
-
-
-### Szybki przykład
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function() {
- my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-Zatrzymuje nagrywanie pliku audio.
-
- media.stopRecord();
-
-
-### Obsługiwane platformy
-
-* Android
-* iOS
-* Windows Phone 7 i 8
-* Windows
-
-### Szybki przykład
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- }
- );
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 seconds
- setTimeout(function() {
- mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### Dziwactwa Tizen
-
-* Nie obsługiwane na Tizen urządzenia.
-
-## MediaError
-
-Gdy wystąpi błąd, funkcja wywołania zwrotnego `mediaError` zwracany jest obiekt `MediaError`.
-
-### Właściwości
-
-* **Kod**: jeden z kodów błędów wstępnie zdefiniowanych poniżej.
-
-* **wiadomość**: komunikat o błędzie, opisując szczegóły błędu.
-
-### Stałe
-
-* `MediaError.MEDIA_ERR_ABORTED`= 1
-* `MediaError.MEDIA_ERR_NETWORK`= 2
-* `MediaError.MEDIA_ERR_DECODE`= 3
-* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
diff --git a/doc/ru/index.md b/doc/ru/index.md
deleted file mode 100644
index 21ce46c20..000000000
--- a/doc/ru/index.md
+++ /dev/null
@@ -1,494 +0,0 @@
-
-
-# cordova-plugin-media
-
-Этот плагин предоставляет возможность записывать и воспроизводить аудио файлы на устройство.
-
-**Примечание**: Текущая реализация не соответствует спецификации W3C для захвата СМИ и предоставляется только для удобства. Будущее осуществление будет придерживаться последней спецификации W3C и может Опознайте текущих API.
-
-## Установка
-
- cordova plugin add cordova-plugin-media
-
-
-## Поддерживаемые платформы
-
-* Android
-* BlackBerry 10
-* iOS
-* Windows Phone 7 и 8
-* Tizen
-* Windows 8
-
-## Windows Phone причуды
-
-* Только один файл может воспроизводиться одновременно.
-
-* Существуют строгие ограничения в отношении как ваше приложение взаимодействует с другими средствами массовой информации. Смотрите в [документации Microsoft для подробной информации][1].
-
- [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx
-
-## Аудио и видео
-
- var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### Параметры
-
-* **src**: URI, содержащий аудио-контент. *(DOMString)*
-
-* **mediaSuccess**: (необязательно) обратного вызова, который выполняется после `Media` объект завершения текущего воспроизведения, записи или стоп действий. *(Функция)*
-
-* **mediaError**: (необязательно) обратного вызова, который выполняется при возникновении ошибки. *(Функция)*
-
-* **mediaStatus**: (необязательно) обратного вызова, который выполняется для отображения изменений состояния. *(Функция)*
-
-### Константы
-
-Следующие константы сообщается как единственный параметр для `mediaStatus` обратного вызова:
-
-* `Media.MEDIA_NONE` = 0;
-* `Media.MEDIA_STARTING` = 1;
-* `Media.MEDIA_RUNNING` = 2;
-* `Media.MEDIA_PAUSED` = 3;
-* `Media.MEDIA_STOPPED` = 4;
-
-### Методы
-
-* `media.getCurrentPosition`: Возвращает текущую позицию в аудиофайл.
-
-* `media.getDuration`: Возвращает продолжительность звукового файла.
-
-* `media.play`: Начать или возобновить воспроизведение звукового файла.
-
-* `media.pause`: Приостановка воспроизведения звукового файла.
-
-* `media.release`: Выпускает аудио ресурсы базовой операционной системы.
-
-* `media.seekTo`: Перемещает положение в пределах звукового файла.
-
-* `media.setVolume`: Задайте громкость воспроизведения звука.
-
-* `media.startRecord`: Начните запись звукового файла.
-
-* `media.stopRecord`: Остановите запись аудио файлов.
-
-* `media.stop`: Остановка воспроизведения звукового файла.
-
-### Дополнительные ReadOnly параметры
-
-* **позиции**: позиция в аудио воспроизведения в секундах.
-
- * Не автоматически обновляются во время игры; Вызовите `getCurrentPosition` для обновления.
-
-* **Продолжительность**: продолжительность СМИ, в секундах.
-
-## media.getCurrentPosition
-
-Возвращает текущую позицию в звуковой файл. Также обновляет `Media` объекта `position` параметр.
-
- media.getCurrentPosition(mediaSuccess, [mediaError]);
-
-
-### Параметры
-
-* **mediaSuccess**: обратный вызов, который передается в текущую позицию в секундах.
-
-* **mediaError**: (необязательно) обратного вызова для выполнения, если происходит ошибка.
-
-### Краткий пример
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Update media position every second
- var mediaTimer = setInterval(function () {
- // get media position
- my_media.getCurrentPosition(
- // success callback
- function (position) {
- if (position > -1) {
- console.log((position) + " sec");
- }
- },
- // error callback
- function (e) {
- console.log("Error getting pos=" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-Возвращает продолжительность аудио файла в секундах. Если длительность неизвестна, она возвращает значение -1.
-
- media.getDuration();
-
-
-### Краткий пример
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(function() {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = my_media.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + " sec";
- }
- }, 100);
-
-
-## Media.Pause
-
-Приостанавливает воспроизведение звукового файла.
-
- media.pause();
-
-
-### Краткий пример
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () { console.log("playAudio():Audio Success"); },
- // error callback
- function (err) { console.log("playAudio():Audio Error: " + err); }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function () {
- media.pause();
- }, 10000);
- }
-
-
-## Media.Play
-
-Запускает или возобновляет воспроизведение звукового файла.
-
- media.play();
-
-
-### Краткий пример
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function (err) {
- console.log("playAudio():Audio Error: " + err);
- }
- );
- // Play audio
- my_media.play();
- }
-
-
-### Особенности iOS
-
-* **numberOfLoops**: этот параметр, чтобы передать `play` метод, чтобы указать количество раз, вы хотите, чтобы средства массовой информации файла для воспроизведения, например:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
-* **playAudioWhenScreenIsLocked**: передайте этот параметр для `play` метод, чтобы указать, хотите ли вы разрешить воспроизведение, когда экран заблокирован. Если значение `true` (значение по умолчанию), состояние оборудования безгласную кнопку игнорируется, например:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
-* **Порядок поиска файла**: когда предоставляется только имя файла или простой путь, iOS ищет в `www` каталог для файла, а затем в приложении `documents/tmp` каталога:
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-Освобождает ресурсы аудио базовой операционной системы. Это особенно важно для Android, так как существует конечное количество экземпляров OpenCore для воспроизведения мультимедиа. Приложения должны вызвать `release` функция для любого `Media` ресурс, который больше не нужен.
-
- media.release();
-
-
-### Краткий пример
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- my_media.play();
- my_media.stop();
- my_media.release();
-
-
-## media.seekTo
-
-Задает текущую позицию в течение звукового файла.
-
- media.seekTo(milliseconds);
-
-
-### Параметры
-
-* **МС**: позиции задать позицию воспроизведения в аудио, в миллисекундах.
-
-### Краткий пример
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
- my_media.play();
- // SeekTo to 10 seconds after 5 seconds
- setTimeout(function() {
- my_media.seekTo(10000);
- }, 5000);
-
-
-### Особенности BlackBerry 10
-
-* Не поддерживается на устройствах BlackBerry OS 5.
-
-## media.setVolume
-
-Задайте громкость звукового файла.
-
- media.setVolume(volume);
-
-
-### Параметры
-
-* **объем**: тома, чтобы задать для воспроизведения. Значение должно быть в диапазоне от 0.0 до 1.0.
-
-### Поддерживаемые платформы
-
-* Android
-* iOS
-
-### Краткий пример
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- });
-
- // Play audio
- my_media.play();
-
- // Mute volume after 2 seconds
- setTimeout(function() {
- my_media.setVolume('0.0');
- }, 2000);
-
- // Set volume to 1.0 after 5 seconds
- setTimeout(function() {
- my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-Начинает запись аудио файлов.
-
- media.startRecord();
-
-
-### Поддерживаемые платформы
-
-* Android
-* iOS
-* Windows Phone 7 и 8
-* Windows 8
-
-### Краткий пример
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- });
-
- // Record audio
- mediaRec.startRecord();
- }
-
-
-### Особенности Android
-
-* Android устройств записи аудио в формате адаптивной мульти ставка. Указанный файл должен заканчиваться *.amr* расширение.
-
-### Особенности iOS
-
-* iOS только записи в файлы типа *.wav* и возвращает ошибку, если расширение не исправить.
-
-* Если полный путь не указан, запись помещается в приложения `documents/tmp` каталог. Это могут быть доступны через `File` API с помощью `LocalFileSystem.TEMPORARY` . Любой подкаталог, указанный на время записи должны уже существовать.
-
-* Файлы могут быть и сыграны записываются обратно, используя документы URI:
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Совместимости Windows 8
-
-* Если не указан полный путь, запись помещается в каталоге AppData/temp. Это могут быть доступны через `Файл` С помощью API `LocalFileSystem.TEMPORARY` или ' ms-appdata: / / / temp /' URI.
-
-* Любой подкаталог указанного в рекордное время должна уже существовать.
-
-### Особенности Tizen
-
-* Не поддерживается на устройствах Tizen.
-
-## media.stop
-
-Останавливает воспроизведение звукового файла.
-
- media.stop();
-
-
-### Краткий пример
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function() {
- my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-Прекращает запись аудио файлов.
-
- media.stopRecord();
-
-
-### Поддерживаемые платформы
-
-* Android
-* iOS
-* Windows Phone 7 и 8
-* Windows 8
-
-### Краткий пример
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- }
- );
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 seconds
- setTimeout(function() {
- mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### Особенности Tizen
-
-* Не поддерживается на устройствах Tizen.
-
-## MediaError
-
-A `MediaError` объект возвращается к `mediaError` функции обратного вызова при возникновении ошибки.
-
-### Параметры
-
-* **code**: один из стандартных кодов ошибок, перечисленных ниже.
-
-* **сообщение**: сообщение об ошибке, с подробными сведениями об ошибке.
-
-### Константы
-
-* `MediaError.MEDIA_ERR_ABORTED`= 1
-* `MediaError.MEDIA_ERR_NETWORK`= 2
-* `MediaError.MEDIA_ERR_DECODE`= 3
-* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
diff --git a/doc/zh/README.md b/doc/zh/README.md
deleted file mode 100644
index 50ee4398a..000000000
--- a/doc/zh/README.md
+++ /dev/null
@@ -1,509 +0,0 @@
-
-
-# cordova-plugin-media
-
-[](https://travis-ci.org/apache/cordova-plugin-media)
-
-這個外掛程式提供錄製和播放設備上的音訊檔的能力。
-
-**注**: 當前的實現並不遵循 W3C 規範的媒體捕獲和僅用於提供方便。 將來的實現將堅持以最新的 W3C 規範和可能棄用當前 Api。
-
-這個外掛程式定義的全球 `Media` 建構函式。
-
-雖然在全球範圍內,它不可用直到 `deviceready` 事件之後。
-
- document.addEventListener("deviceready", onDeviceReady, false);
- function onDeviceReady() {
- console.log(Media);
- }
-
-
-## 安裝
-
- cordova plugin add cordova-plugin-media
-
-
-## 支援的平臺
-
- * Android 系統
- * 黑莓 10
- * iOS
- * Windows Phone 7 和 8
- * Tizen
- * Windows 8
- * Windows
- * 瀏覽器
-
-## Windows Phone 怪癖
-
- * 只有一個媒體檔案,可以播放一次。
-
- * 沒有嚴格限制對您的應用程式與其他媒體的對話模式。 請參見[Microsoft 文檔的詳細資訊](http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx).
-
-## 媒體
-
- var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### 參數
-
- * **src**: 包含音訊內容的 URI。*() DOMString*
-
- * **mediaSuccess**: (可選) 後執行的回檔 `Media` 物件已完成當前戲劇、 記錄或停止行動。*(函數)*
-
- * **mediaError**: (可選) 如果錯誤發生時執行的回檔。*(函數)*
-
- * **mediaStatus**: (可選) 執行以指示狀態的更改的回檔。*(函數)*
-
-### 常量
-
-下列常量 `mediaStatus` 回檔報告作為唯一的參數:
-
- * `Media.MEDIA_NONE` = 0;
- * `Media.MEDIA_STARTING` = 1;
- * `Media.MEDIA_RUNNING` = 2;
- * `Media.MEDIA_PAUSED`= 3 ;
- * `Media.MEDIA_STOPPED`= 4 ;
-
-### 方法
-
- * `media.getCurrentPosition`: 返回一個音訊檔內的當前位置。
-
- * `media.getDuration`: 返回一個音訊檔的持續時間。
-
- * `media.play`: 啟動或繼續播放音訊檔。
-
- * `media.pause`: 暫停播放的音訊檔。
-
- * `media.release`: 釋放底層作業系統的音訊資源。
-
- * `media.seekTo`: 在音訊檔內移動的位置。
-
- * `media.setVolume`: 設置音訊播放的音量。
-
- * `media.startRecord`: 開始錄製的音訊檔。
-
- * `media.stopRecord`: 停止錄製的音訊檔。
-
- * `media.stop`: 停止播放音訊檔。
-
-### 附加唯讀參數
-
- * **position**: 內音訊播放,以秒為單位的位置。
-
- * 不會自動更新期間播放 ;調用 `getCurrentPosition` 來更新。
-
- * **duration**: 媒體的持續時間以秒為單位。
-
-## media.getCurrentPosition
-
-返回一個音訊檔內的當前位置。此外可以更新 `Media` 物件 `Position` 參數。
-
- media.getCurrentPosition(mediaSuccess, [mediaError]);
-
-
-### 參數
-
- * **mediaSuccess**: 傳遞的當前的位置,以秒為單位的回檔。
-
- * **mediaError**: (可選) 回檔執行如果發生錯誤。
-
-### 快速的示例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Update media position every second
- var mediaTimer = setInterval(function () {
- // get media position
- my_media.getCurrentPosition(
- // success callback
- function (position) {
- if (position > -1) {
- console.log((position) + " sec");
- }
- },
- // error callback
- function (e) {
- console.log("Error getting pos=" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-返回一個音訊檔的持續時間以秒為單位。如果持續時間是未知的則傳回值為-1。
-
- media.getDuration();
-
-
-### 快速的示例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(function() {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = my_media.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + " sec";
- }
- }, 100);
-
-
-## media.pause
-
-暫停播放音訊檔。
-
- media.pause();
-
-
-### 快速的示例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () { console.log("playAudio():Audio Success"); },
- // error callback
- function (err) { console.log("playAudio():Audio Error: " + err); }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function () {
- media.pause();
- }, 10000);
- }
-
-
-## media.play
-
-開始或繼續播放音訊檔。
-
- media.play();
-
-
-### 快速的示例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function (err) {
- console.log("playAudio():Audio Error: " + err);
- }
- );
- // Play audio
- my_media.play();
- }
-
-
-### iOS 的怪癖
-
- * **numberOfLoops**: 傳遞到此選項 `play` 方法,以指定的次數,你想讓媒體檔案以播放,例如:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
- * **playAudioWhenScreenIsLocked**: 通過此選項可在 `play` 方法,以指定您是否要允許播放時螢幕鎖定。 如果設置為 `true` (預設值),將忽略硬體靜音按鈕的狀態,例如:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
- * **檔搜索順序**: 當只有一個檔的名稱或簡單路徑提供時,搜索中的 iOS `www` 目錄為該檔,然後在應用程式中的 `documents/tmp` 目錄:
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-釋放底層作業系統的音訊資源。 這是安卓系統,特別是重要的因為有一個有限的 OpenCore 實例進行媒體重播。 應用程式應調用 `release` 功能不再需要任何 `Media` 資源。
-
- media.release();
-
-
-### 快速的示例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- my_media.play();
- my_media.stop();
- my_media.release();
-
-
-## media.seekTo
-
-在音訊檔中設置的當前的位置。
-
- media.seekTo(milliseconds);
-
-
-### 參數
-
- * **miliseconds)**: 要以毫秒為單位設置中,音訊的播放位置的位置。
-
-### 快速的示例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
- my_media.play();
- // SeekTo to 10 seconds after 5 seconds
- setTimeout(function() {
- my_media.seekTo(10000);
- }, 5000);
-
-
-### 黑莓 10 怪癖
-
- * 黑莓 OS 5 設備上不支援。
-
-## media.setVolume
-
-設置音訊檔的音量。
-
- media.setVolume(volume);
-
-
-### 參數
-
- * **volume**: 要為播放設置的卷。值必須在 0.0 到 1.0 的範圍內。
-
-### 支援的平臺
-
- * Android 系統
- * iOS
-
-### 快速的示例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- });
-
- // Play audio
- my_media.play();
-
- // Mute volume after 2 seconds
- setTimeout(function() {
- my_media.setVolume('0.0');
- }, 2000);
-
- // Set volume to 1.0 after 5 seconds
- setTimeout(function() {
- my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-開始錄製音訊檔。
-
- media.startRecord();
-
-
-### 支援的平臺
-
- * Android 系統
- * iOS
- * Windows Phone 7 和 8
- * Windows
-
-### 快速的示例
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- });
-
- // Record audio
- mediaRec.startRecord();
- }
-
-
-### Android 的怪癖
-
- * Android 設備音訊格式記錄的自我調整多速率。指定的檔應以*.amr*副檔名結尾。
- * 硬體音量控制有線到媒體卷中,而任何媒體物件是還活著。 一旦最後創建的媒體物件具有 `release()` 在它上面調用,音量控制還原為其預設行為。 因為這會釋放所有媒體物件,控制項也上頁面導航,重置。
-
-### iOS 的怪癖
-
- * iOS 只記錄到檔的類型*.wav*和返回一個錯誤如果檔副檔名不正確。
-
- * 如果未提供的完整路徑,錄音放在應用程式的 `documents/tmp` 目錄。 這可以通過訪問 `File` API 使用 `LocalFileSystem.TEMPORARY` 。 在記錄時指定的任何子目錄中必須已經存在。
-
- * 檔可以記錄和演奏的後面使用的檔的 URI:
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Windows 的怪癖
-
- * Windows 設備可以使用 MP3、 M4A、 WMA 格式錄製音訊。 然而在大多數情況下它是不可能用於 MP3 音訊記錄在*Windows Phone 8.1*設備上,因為 MP3 編碼器是[不附帶 Windows Phone](https://msdn.microsoft.com/en-us/library/windows/apps/windows.media.mediaproperties.mediaencodingprofile.createmp3.aspx).
-
- * 如果沒有提供完整的路徑,錄音被放在應用程式/temp 目錄。這可以通過訪問 `檔` API 使用 `LocalFileSystem.TEMPORARY` 或 ' ms appdata: temp / / /' URI。
-
- * 在記錄時指定的任何子目錄中必須已經存在。
-
-### Tizen 怪癖
-
- * 不支援在 Tizen 設備上。
-
-## media.stop
-
-停止播放音訊檔。
-
- media.stop();
-
-
-### 快速的示例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function() {
- my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-停止錄製的音訊檔。
-
- media.stopRecord();
-
-
-### 支援的平臺
-
- * Android 系統
- * iOS
- * Windows Phone 7 和 8
- * Windows
-
-### 快速的示例
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- }
- );
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 seconds
- setTimeout(function() {
- mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### Tizen 怪癖
-
- * 不支援在 Tizen 設備上。
-
-## MediaError
-
-當發生錯誤時,`mediaError` 回呼函數情況下會返回一個 `MediaError` 物件。
-
-### 屬性
-
- * **code**: 下面列出的預定義的錯誤代碼之一。
-
- * **message**: 錯誤訊息,描述該錯誤的詳細資訊。
-
-### 常量
-
- * `MediaError.MEDIA_ERR_ABORTED`= 1
- * `MediaError.MEDIA_ERR_NETWORK`= 2
- * `MediaError.MEDIA_ERR_DECODE`= 3
- * `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file
diff --git a/doc/zh/index.md b/doc/zh/index.md
deleted file mode 100644
index 78ffe441e..000000000
--- a/doc/zh/index.md
+++ /dev/null
@@ -1,505 +0,0 @@
-
-
-# cordova-plugin-media
-
-這個外掛程式提供錄製和播放設備上的音訊檔的能力。
-
-**注**: 當前的實現並不遵循 W3C 規範的媒體捕獲和僅用於提供方便。 將來的實現將堅持以最新的 W3C 規範和可能棄用當前 Api。
-
-這個外掛程式定義的全球 `Media` 建構函式。
-
-雖然在全球範圍內,它不可用直到 `deviceready` 事件之後。
-
- document.addEventListener("deviceready", onDeviceReady, false);
- function onDeviceReady() {
- console.log(Media);
- }
-
-
-## 安裝
-
- cordova plugin add cordova-plugin-media
-
-
-## 支援的平臺
-
-* Android 系統
-* 黑莓 10
-* iOS
-* Windows Phone 7 和 8
-* Tizen
-* Windows
-
-## Windows Phone 怪癖
-
-* 只有一個媒體檔案,可以播放一次。
-
-* 沒有嚴格限制對您的應用程式與其他媒體的對話模式。 請參見[Microsoft 文檔的詳細資訊][1].
-
- [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx
-
-## 媒體
-
- var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);
-
-
-### 參數
-
-* **src**: 包含音訊內容的 URI。*() DOMString*
-
-* **mediaSuccess**: (可選) 後執行的回檔 `Media` 物件已完成當前戲劇、 記錄或停止行動。*(函數)*
-
-* **mediaError**: (可選) 如果錯誤發生時執行的回檔。*(函數)*
-
-* **mediaStatus**: (可選) 執行以指示狀態的更改的回檔。*(函數)*
-
-### 常量
-
-下列常量 `mediaStatus` 回檔報告作為唯一的參數:
-
-* `Media.MEDIA_NONE` = 0;
-* `Media.MEDIA_STARTING` = 1;
-* `Media.MEDIA_RUNNING` = 2;
-* `Media.MEDIA_PAUSED`= 3 ;
-* `Media.MEDIA_STOPPED`= 4 ;
-
-### 方法
-
-* `media.getCurrentPosition`: 返回一個音訊檔內的當前位置。
-
-* `media.getDuration`: 返回一個音訊檔的持續時間。
-
-* `media.play`: 啟動或繼續播放音訊檔。
-
-* `media.pause`: 暫停播放的音訊檔。
-
-* `media.release`: 釋放底層作業系統的音訊資源。
-
-* `media.seekTo`: 在音訊檔內移動的位置。
-
-* `media.setVolume`: 設置音訊播放的音量。
-
-* `media.startRecord`: 開始錄製的音訊檔。
-
-* `media.stopRecord`: 停止錄製的音訊檔。
-
-* `media.stop`: 停止播放音訊檔。
-
-### 附加唯讀參數
-
-* **position**: 內音訊播放,以秒為單位的位置。
-
- * 不會自動更新期間播放 ;調用 `getCurrentPosition` 來更新。
-
-* **duration**: 媒體的持續時間以秒為單位。
-
-## media.getCurrentPosition
-
-返回一個音訊檔內的當前位置。此外可以更新 `Media` 物件 `Position` 參數。
-
- media.getCurrentPosition(mediaSuccess, [mediaError]);
-
-
-### 參數
-
-* **mediaSuccess**: 傳遞的當前的位置,以秒為單位的回檔。
-
-* **mediaError**: (可選) 回檔執行如果發生錯誤。
-
-### 快速的示例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Update media position every second
- var mediaTimer = setInterval(function () {
- // get media position
- my_media.getCurrentPosition(
- // success callback
- function (position) {
- if (position > -1) {
- console.log((position) + " sec");
- }
- },
- // error callback
- function (e) {
- console.log("Error getting pos=" + e);
- }
- );
- }, 1000);
-
-
-## media.getDuration
-
-返回一個音訊檔的持續時間以秒為單位。如果持續時間是未知的則傳回值為-1。
-
- media.getDuration();
-
-
-### 快速的示例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(function() {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = my_media.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('audio_duration').innerHTML = (dur) + " sec";
- }
- }, 100);
-
-
-## media.pause
-
-暫停播放音訊檔。
-
- media.pause();
-
-
-### 快速的示例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () { console.log("playAudio():Audio Success"); },
- // error callback
- function (err) { console.log("playAudio():Audio Error: " + err); }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function () {
- media.pause();
- }, 10000);
- }
-
-
-## media.play
-
-開始或繼續播放音訊檔。
-
- media.play();
-
-
-### 快速的示例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function () {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function (err) {
- console.log("playAudio():Audio Error: " + err);
- }
- );
- // Play audio
- my_media.play();
- }
-
-
-### iOS 的怪癖
-
-* **numberOfLoops**: 傳遞到此選項 `play` 方法,以指定的次數,你想讓媒體檔案以播放,例如:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ numberOfLoops: 2 })
-
-
-* **playAudioWhenScreenIsLocked**: 通過此選項可在 `play` 方法,以指定您是否要允許播放時螢幕鎖定。 如果設置為 `true` (預設值),將忽略硬體靜音按鈕的狀態,例如:
-
- var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3")
- myMedia.play({ playAudioWhenScreenIsLocked : false })
-
-
-* **檔搜索順序**: 當只有一個檔的名稱或簡單路徑提供時,搜索中的 iOS `www` 目錄為該檔,然後在應用程式中的 `documents/tmp` 目錄:
-
- var myMedia = new Media("audio/beer.mp3")
- myMedia.play() // first looks for file in www/audio/beer.mp3 then in /documents/tmp/audio/beer.mp3
-
-
-## media.release
-
-釋放底層作業系統的音訊資源。 這是安卓系統,特別是重要的因為有一個有限的 OpenCore 實例進行媒體重播。 應用程式應調用 `release` 功能不再需要任何 `Media` 資源。
-
- media.release();
-
-
-### 快速的示例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
-
- my_media.play();
- my_media.stop();
- my_media.release();
-
-
-## media.seekTo
-
-在音訊檔中設置的當前的位置。
-
- media.seekTo(milliseconds);
-
-
-### 參數
-
-* **miliseconds)**: 要以毫秒為單位設置中,音訊的播放位置的位置。
-
-### 快速的示例
-
- // Audio player
- //
- var my_media = new Media(src, onSuccess, onError);
- my_media.play();
- // SeekTo to 10 seconds after 5 seconds
- setTimeout(function() {
- my_media.seekTo(10000);
- }, 5000);
-
-
-### 黑莓 10 怪癖
-
-* 黑莓 OS 5 設備上不支援。
-
-## media.setVolume
-
-設置音訊檔的音量。
-
- media.setVolume(volume);
-
-
-### 參數
-
-* **volume**: 要為播放設置的卷。值必須在 0.0 到 1.0 的範圍內。
-
-### 支援的平臺
-
-* Android 系統
-* iOS
-
-### 快速的示例
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- });
-
- // Play audio
- my_media.play();
-
- // Mute volume after 2 seconds
- setTimeout(function() {
- my_media.setVolume('0.0');
- }, 2000);
-
- // Set volume to 1.0 after 5 seconds
- setTimeout(function() {
- my_media.setVolume('1.0');
- }, 5000);
- }
-
-
-## media.startRecord
-
-開始錄製音訊檔。
-
- media.startRecord();
-
-
-### 支援的平臺
-
-* Android 系統
-* iOS
-* Windows Phone 7 和 8
-* Windows
-
-### 快速的示例
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- });
-
- // Record audio
- mediaRec.startRecord();
- }
-
-
-### Android 的怪癖
-
-* Android 設備音訊格式記錄的自我調整多速率。指定的檔應以*.amr*副檔名結尾。
-* 硬體音量控制有線到媒體卷中,而任何媒體物件是還活著。 一旦最後創建的媒體物件具有 `release()` 在它上面調用,音量控制還原為其預設行為。 因為這會釋放所有媒體物件,控制項也上頁面導航,重置。
-
-### iOS 的怪癖
-
-* iOS 只記錄到檔的類型*.wav*和返回一個錯誤如果檔副檔名不正確。
-
-* 如果未提供的完整路徑,錄音放在應用程式的 `documents/tmp` 目錄。 這可以通過訪問 `File` API 使用 `LocalFileSystem.TEMPORARY` 。 在記錄時指定的任何子目錄中必須已經存在。
-
-* 檔可以記錄和演奏的後面使用的檔的 URI:
-
- var myMedia = new Media("documents://beer.mp3")
-
-
-### Windows 的怪癖
-
-* 如果沒有提供完整的路徑,錄音被放在應用程式/temp 目錄。這可以通過訪問 `檔` API 使用 `LocalFileSystem.TEMPORARY` 或 ' ms appdata: temp / / /' URI。
-
-* 在記錄時指定的任何子目錄中必須已經存在。
-
-### 泰怪癖
-
-* 不支援在 Tizen 設備上。
-
-## media.stop
-
-停止播放音訊檔。
-
- media.stop();
-
-
-### 簡單的例子
-
- // Play audio
- //
- function playAudio(url) {
- // Play the audio file at url
- var my_media = new Media(url,
- // success callback
- function() {
- console.log("playAudio():Audio Success");
- },
- // error callback
- function(err) {
- console.log("playAudio():Audio Error: "+err);
- }
- );
-
- // Play audio
- my_media.play();
-
- // Pause after 10 seconds
- setTimeout(function() {
- my_media.stop();
- }, 10000);
- }
-
-
-## media.stopRecord
-
-停止錄製的音訊檔。
-
- media.stopRecord();
-
-
-### 支援的平臺
-
-* 安卓系統
-* iOS
-* Windows Phone 7 和 8
-* Windows
-
-### 簡單的例子
-
- // Record audio
- //
- function recordAudio() {
- var src = "myrecording.mp3";
- var mediaRec = new Media(src,
- // success callback
- function() {
- console.log("recordAudio():Audio Success");
- },
-
- // error callback
- function(err) {
- console.log("recordAudio():Audio Error: "+ err.code);
- }
- );
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 seconds
- setTimeout(function() {
- mediaRec.stopRecord();
- }, 10000);
- }
-
-
-### 泰怪癖
-
-* 不支援在 Tizen 設備上。
-
-## MediaError
-
-當發生錯誤時,`mediaError` 回呼函數情況下會返回一個 `MediaError` 物件。
-
-### 屬性
-
-* **code**: 下面列出的預定義的錯誤代碼之一。
-
-* **message**: 錯誤訊息,描述該錯誤的詳細資訊。
-
-### 常量
-
-* `MediaError.MEDIA_ERR_ABORTED`= 1
-* `MediaError.MEDIA_ERR_NETWORK`= 2
-* `MediaError.MEDIA_ERR_DECODE`= 3
-* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 000000000..13c308fea
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,4212 @@
+{
+ "name": "cordova-plugin-media",
+ "version": "7.0.1-dev",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "cordova-plugin-media",
+ "version": "7.0.1-dev",
+ "license": "Apache-2.0",
+ "devDependencies": {
+ "@cordova/eslint-config": "^5.0.0"
+ },
+ "engines": {
+ "cordovaDependencies": {
+ "3.0.0": {
+ "cordova-android": ">=6.1.0"
+ },
+ "4.0.0": {
+ "cordova-android": ">=6.3.0"
+ },
+ "6.0.0": {
+ "cordova-android": ">=10.0.0"
+ },
+ "7.0.0": {
+ "cordova-android": ">=12.0.0"
+ },
+ "8.0.0": {
+ "cordova": ">100"
+ }
+ }
+ }
+ },
+ "node_modules/@aashutoshrathi/word-wrap": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
+ "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@cordova/eslint-config": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@cordova/eslint-config/-/eslint-config-5.0.0.tgz",
+ "integrity": "sha512-tBSV8LbT6RjWsO2lSp45Y+zU7hfXhGMGhfYTZjDrjzli87WOgE6IAS37k6F45JNoGq1XlCJEVkCWwz4KCF8Scw==",
+ "dev": true,
+ "dependencies": {
+ "eslint": "^8.31.0",
+ "eslint-config-standard": "^17.0.0",
+ "eslint-plugin-import": "^2.27.2",
+ "eslint-plugin-n": "^15.6.1",
+ "eslint-plugin-promise": "^6.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+ "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.7.0.tgz",
+ "integrity": "sha512-+HencqxU7CFJnQb7IKtuNBqS6Yx3Tz4kOL8BJXo+JyeiBm5MEX6pO8onXDkjrkCRlfYXS1Axro15ZjVFe9YgsA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz",
+ "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.47.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz",
+ "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
+ "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==",
+ "dev": true,
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^1.2.1",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+ "dev": true
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@types/json5": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
+ "dev": true
+ },
+ "node_modules/acorn": {
+ "version": "8.10.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
+ "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
+ "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "is-array-buffer": "^3.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz",
+ "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "get-intrinsic": "^1.1.3",
+ "is-string": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.findlastindex": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.2.tgz",
+ "integrity": "sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0",
+ "get-intrinsic": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz",
+ "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz",
+ "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz",
+ "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==",
+ "dev": true,
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.0",
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "get-intrinsic": "^1.2.1",
+ "is-array-buffer": "^3.0.2",
+ "is-shared-array-buffer": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/builtins": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz",
+ "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.0.0"
+ }
+ },
+ "node_modules/builtins/node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz",
+ "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==",
+ "dev": true,
+ "dependencies": {
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz",
+ "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==",
+ "dev": true,
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.0",
+ "arraybuffer.prototype.slice": "^1.0.1",
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "es-set-tostringtag": "^2.0.1",
+ "es-to-primitive": "^1.2.1",
+ "function.prototype.name": "^1.1.5",
+ "get-intrinsic": "^1.2.1",
+ "get-symbol-description": "^1.0.0",
+ "globalthis": "^1.0.3",
+ "gopd": "^1.0.1",
+ "has": "^1.0.3",
+ "has-property-descriptors": "^1.0.0",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.5",
+ "is-array-buffer": "^3.0.2",
+ "is-callable": "^1.2.7",
+ "is-negative-zero": "^2.0.2",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.2",
+ "is-string": "^1.0.7",
+ "is-typed-array": "^1.1.10",
+ "is-weakref": "^1.0.2",
+ "object-inspect": "^1.12.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.4",
+ "regexp.prototype.flags": "^1.5.0",
+ "safe-array-concat": "^1.0.0",
+ "safe-regex-test": "^1.0.0",
+ "string.prototype.trim": "^1.2.7",
+ "string.prototype.trimend": "^1.0.6",
+ "string.prototype.trimstart": "^1.0.6",
+ "typed-array-buffer": "^1.0.0",
+ "typed-array-byte-length": "^1.0.0",
+ "typed-array-byte-offset": "^1.0.0",
+ "typed-array-length": "^1.0.4",
+ "unbox-primitive": "^1.0.2",
+ "which-typed-array": "^1.1.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
+ "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.3",
+ "has": "^1.0.3",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-shim-unscopables": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
+ "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "dependencies": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.47.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz",
+ "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.2",
+ "@eslint/js": "^8.47.0",
+ "@humanwhocodes/config-array": "^0.11.10",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-config-standard": {
+ "version": "17.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz",
+ "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^8.0.1",
+ "eslint-plugin-import": "^2.25.2",
+ "eslint-plugin-n": "^15.0.0 || ^16.0.0 ",
+ "eslint-plugin-promise": "^6.0.0"
+ }
+ },
+ "node_modules/eslint-import-resolver-node": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
+ "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^3.2.7",
+ "is-core-module": "^2.13.0",
+ "resolve": "^1.22.4"
+ }
+ },
+ "node_modules/eslint-import-resolver-node/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-module-utils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz",
+ "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^3.2.7"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-es": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz",
+ "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==",
+ "dev": true,
+ "dependencies": {
+ "eslint-utils": "^2.0.0",
+ "regexpp": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=4.19.1"
+ }
+ },
+ "node_modules/eslint-plugin-es/node_modules/eslint-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
+ "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ }
+ },
+ "node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-plugin-import": {
+ "version": "2.28.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz",
+ "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==",
+ "dev": true,
+ "dependencies": {
+ "array-includes": "^3.1.6",
+ "array.prototype.findlastindex": "^1.2.2",
+ "array.prototype.flat": "^1.3.1",
+ "array.prototype.flatmap": "^1.3.1",
+ "debug": "^3.2.7",
+ "doctrine": "^2.1.0",
+ "eslint-import-resolver-node": "^0.3.7",
+ "eslint-module-utils": "^2.8.0",
+ "has": "^1.0.3",
+ "is-core-module": "^2.13.0",
+ "is-glob": "^4.0.3",
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.6",
+ "object.groupby": "^1.0.0",
+ "object.values": "^1.1.6",
+ "semver": "^6.3.1",
+ "tsconfig-paths": "^3.14.2"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eslint-plugin-n": {
+ "version": "15.7.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz",
+ "integrity": "sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==",
+ "dev": true,
+ "dependencies": {
+ "builtins": "^5.0.1",
+ "eslint-plugin-es": "^4.1.0",
+ "eslint-utils": "^3.0.0",
+ "ignore": "^5.1.1",
+ "is-core-module": "^2.11.0",
+ "minimatch": "^3.1.2",
+ "resolve": "^1.22.1",
+ "semver": "^7.3.8"
+ },
+ "engines": {
+ "node": ">=12.22.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-n/node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint-plugin-promise": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz",
+ "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-utils": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+ "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^2.0.0"
+ },
+ "engines": {
+ "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=5"
+ }
+ },
+ "node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+ "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+ "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true
+ },
+ "node_modules/fastq": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
+ "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+ "dev": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+ "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+ "dev": true,
+ "dependencies": {
+ "flatted": "^3.1.0",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
+ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
+ "dev": true
+ },
+ "node_modules/for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "dev": true,
+ "dependencies": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
+ "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.19.0",
+ "functions-have-names": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
+ "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+ "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "13.21.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz",
+ "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
+ "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+ "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-bigints": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+ "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
+ "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+ "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "node_modules/internal-slot": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
+ "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.2.0",
+ "has": "^1.0.3",
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
+ "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.0",
+ "is-typed-array": "^1.1.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "dev": true,
+ "dependencies": {
+ "has-bigints": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.13.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz",
+ "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+ "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+ "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+ "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+ "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
+ "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+ "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "dev": true,
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+ "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
+ "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
+ "dev": true,
+ "dependencies": {
+ "which-typed-array": "^1.1.11"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+ "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true
+ },
+ "node_modules/json5": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "node_modules/object-inspect": {
+ "version": "1.12.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
+ "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
+ "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "has-symbols": "^1.0.3",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz",
+ "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.groupby": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.0.tgz",
+ "integrity": "sha512-70MWG6NfRH9GnbZOikuhPPYzpUpof9iW2J9E4dW7FXTqPNb6rllE6u39SKwwiNh8lCwX3DDb5OgcKGiEBrTTyw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.21.2",
+ "get-intrinsic": "^1.2.1"
+ }
+ },
+ "node_modules/object.values": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz",
+ "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
+ "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
+ "dev": true,
+ "dependencies": {
+ "@aashutoshrathi/word-wrap": "^1.2.3",
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz",
+ "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "functions-have-names": "^1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regexpp": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
+ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.4",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz",
+ "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-array-concat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz",
+ "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.0",
+ "has-symbols": "^1.0.3",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
+ "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.3",
+ "is-regex": "^1.1.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz",
+ "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz",
+ "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz",
+ "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true
+ },
+ "node_modules/tsconfig-paths": {
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz",
+ "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==",
+ "dev": true,
+ "dependencies": {
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.2",
+ "minimist": "^1.2.6",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz",
+ "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.1",
+ "is-typed-array": "^1.1.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz",
+ "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "has-proto": "^1.0.1",
+ "is-typed-array": "^1.1.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz",
+ "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==",
+ "dev": true,
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "has-proto": "^1.0.1",
+ "is-typed-array": "^1.1.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
+ "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "is-typed-array": "^1.1.9"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+ "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.0.3",
+ "which-boxed-primitive": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+ "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+ "dev": true,
+ "dependencies": {
+ "is-bigint": "^1.0.1",
+ "is-boolean-object": "^1.1.0",
+ "is-number-object": "^1.0.4",
+ "is-string": "^1.0.5",
+ "is-symbol": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
+ "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==",
+ "dev": true,
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ },
+ "dependencies": {
+ "@aashutoshrathi/word-wrap": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
+ "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
+ "dev": true
+ },
+ "@cordova/eslint-config": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@cordova/eslint-config/-/eslint-config-5.0.0.tgz",
+ "integrity": "sha512-tBSV8LbT6RjWsO2lSp45Y+zU7hfXhGMGhfYTZjDrjzli87WOgE6IAS37k6F45JNoGq1XlCJEVkCWwz4KCF8Scw==",
+ "dev": true,
+ "requires": {
+ "eslint": "^8.31.0",
+ "eslint-config-standard": "^17.0.0",
+ "eslint-plugin-import": "^2.27.2",
+ "eslint-plugin-n": "^15.6.1",
+ "eslint-plugin-promise": "^6.1.1"
+ }
+ },
+ "@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+ "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^3.3.0"
+ }
+ },
+ "@eslint-community/regexpp": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.7.0.tgz",
+ "integrity": "sha512-+HencqxU7CFJnQb7IKtuNBqS6Yx3Tz4kOL8BJXo+JyeiBm5MEX6pO8onXDkjrkCRlfYXS1Axro15ZjVFe9YgsA==",
+ "dev": true
+ },
+ "@eslint/eslintrc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz",
+ "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ }
+ },
+ "@eslint/js": {
+ "version": "8.47.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz",
+ "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==",
+ "dev": true
+ },
+ "@humanwhocodes/config-array": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
+ "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==",
+ "dev": true,
+ "requires": {
+ "@humanwhocodes/object-schema": "^1.2.1",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.5"
+ }
+ },
+ "@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true
+ },
+ "@humanwhocodes/object-schema": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+ "dev": true
+ },
+ "@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true
+ },
+ "@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ }
+ },
+ "@types/json5": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
+ "dev": true
+ },
+ "acorn": {
+ "version": "8.10.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
+ "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "requires": {}
+ },
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "array-buffer-byte-length": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
+ "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "is-array-buffer": "^3.0.1"
+ }
+ },
+ "array-includes": {
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz",
+ "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "get-intrinsic": "^1.1.3",
+ "is-string": "^1.0.7"
+ }
+ },
+ "array.prototype.findlastindex": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.2.tgz",
+ "integrity": "sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0",
+ "get-intrinsic": "^1.1.3"
+ }
+ },
+ "array.prototype.flat": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz",
+ "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0"
+ }
+ },
+ "array.prototype.flatmap": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz",
+ "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0"
+ }
+ },
+ "arraybuffer.prototype.slice": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz",
+ "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==",
+ "dev": true,
+ "requires": {
+ "array-buffer-byte-length": "^1.0.0",
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "get-intrinsic": "^1.2.1",
+ "is-array-buffer": "^3.0.2",
+ "is-shared-array-buffer": "^1.0.2"
+ }
+ },
+ "available-typed-arrays": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "builtins": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz",
+ "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==",
+ "dev": true,
+ "requires": {
+ "semver": "^7.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ }
+ },
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true
+ },
+ "define-properties": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz",
+ "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==",
+ "dev": true,
+ "requires": {
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "es-abstract": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz",
+ "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==",
+ "dev": true,
+ "requires": {
+ "array-buffer-byte-length": "^1.0.0",
+ "arraybuffer.prototype.slice": "^1.0.1",
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "es-set-tostringtag": "^2.0.1",
+ "es-to-primitive": "^1.2.1",
+ "function.prototype.name": "^1.1.5",
+ "get-intrinsic": "^1.2.1",
+ "get-symbol-description": "^1.0.0",
+ "globalthis": "^1.0.3",
+ "gopd": "^1.0.1",
+ "has": "^1.0.3",
+ "has-property-descriptors": "^1.0.0",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.5",
+ "is-array-buffer": "^3.0.2",
+ "is-callable": "^1.2.7",
+ "is-negative-zero": "^2.0.2",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.2",
+ "is-string": "^1.0.7",
+ "is-typed-array": "^1.1.10",
+ "is-weakref": "^1.0.2",
+ "object-inspect": "^1.12.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.4",
+ "regexp.prototype.flags": "^1.5.0",
+ "safe-array-concat": "^1.0.0",
+ "safe-regex-test": "^1.0.0",
+ "string.prototype.trim": "^1.2.7",
+ "string.prototype.trimend": "^1.0.6",
+ "string.prototype.trimstart": "^1.0.6",
+ "typed-array-buffer": "^1.0.0",
+ "typed-array-byte-length": "^1.0.0",
+ "typed-array-byte-offset": "^1.0.0",
+ "typed-array-length": "^1.0.4",
+ "unbox-primitive": "^1.0.2",
+ "which-typed-array": "^1.1.10"
+ }
+ },
+ "es-set-tostringtag": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
+ "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
+ "dev": true,
+ "requires": {
+ "get-intrinsic": "^1.1.3",
+ "has": "^1.0.3",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "es-shim-unscopables": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
+ "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true
+ },
+ "eslint": {
+ "version": "8.47.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz",
+ "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==",
+ "dev": true,
+ "requires": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.2",
+ "@eslint/js": "^8.47.0",
+ "@humanwhocodes/config-array": "^0.11.10",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ }
+ },
+ "eslint-config-standard": {
+ "version": "17.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz",
+ "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==",
+ "dev": true,
+ "requires": {}
+ },
+ "eslint-import-resolver-node": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
+ "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.2.7",
+ "is-core-module": "^2.13.0",
+ "resolve": "^1.22.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "eslint-module-utils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz",
+ "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.2.7"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "eslint-plugin-es": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz",
+ "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==",
+ "dev": true,
+ "requires": {
+ "eslint-utils": "^2.0.0",
+ "regexpp": "^3.0.0"
+ },
+ "dependencies": {
+ "eslint-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
+ "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^1.1.0"
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-plugin-import": {
+ "version": "2.28.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz",
+ "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==",
+ "dev": true,
+ "requires": {
+ "array-includes": "^3.1.6",
+ "array.prototype.findlastindex": "^1.2.2",
+ "array.prototype.flat": "^1.3.1",
+ "array.prototype.flatmap": "^1.3.1",
+ "debug": "^3.2.7",
+ "doctrine": "^2.1.0",
+ "eslint-import-resolver-node": "^0.3.7",
+ "eslint-module-utils": "^2.8.0",
+ "has": "^1.0.3",
+ "is-core-module": "^2.13.0",
+ "is-glob": "^4.0.3",
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.6",
+ "object.groupby": "^1.0.0",
+ "object.values": "^1.1.6",
+ "semver": "^6.3.1",
+ "tsconfig-paths": "^3.14.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ }
+ }
+ },
+ "eslint-plugin-n": {
+ "version": "15.7.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz",
+ "integrity": "sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==",
+ "dev": true,
+ "requires": {
+ "builtins": "^5.0.1",
+ "eslint-plugin-es": "^4.1.0",
+ "eslint-utils": "^3.0.0",
+ "ignore": "^5.1.1",
+ "is-core-module": "^2.11.0",
+ "minimatch": "^3.1.2",
+ "resolve": "^1.22.1",
+ "semver": "^7.3.8"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "eslint-plugin-promise": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz",
+ "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==",
+ "dev": true,
+ "requires": {}
+ },
+ "eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ }
+ },
+ "eslint-utils": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+ "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^2.0.0"
+ },
+ "dependencies": {
+ "eslint-visitor-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+ "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true
+ },
+ "espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "requires": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ }
+ },
+ "esquery": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+ "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.1.0"
+ }
+ },
+ "esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.2.0"
+ }
+ },
+ "estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true
+ },
+ "fastq": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
+ "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+ "dev": true,
+ "requires": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^3.0.4"
+ }
+ },
+ "find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "flat-cache": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+ "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+ "dev": true,
+ "requires": {
+ "flatted": "^3.1.0",
+ "rimraf": "^3.0.2"
+ }
+ },
+ "flatted": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
+ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
+ "dev": true
+ },
+ "for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "function.prototype.name": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
+ "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.19.0",
+ "functions-have-names": "^1.2.2"
+ }
+ },
+ "functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true
+ },
+ "get-intrinsic": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
+ "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3"
+ }
+ },
+ "get-symbol-description": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+ "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.1"
+ }
+ },
+ "glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.3"
+ }
+ },
+ "globals": {
+ "version": "13.21.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz",
+ "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.20.2"
+ }
+ },
+ "globalthis": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
+ "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3"
+ }
+ },
+ "gopd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+ "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "dev": true,
+ "requires": {
+ "get-intrinsic": "^1.1.3"
+ }
+ },
+ "graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-bigints": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "has-property-descriptors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+ "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "dev": true,
+ "requires": {
+ "get-intrinsic": "^1.1.1"
+ }
+ },
+ "has-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
+ "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+ "dev": true
+ },
+ "has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "dev": true
+ },
+ "has-tostringtag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+ "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.2"
+ }
+ },
+ "ignore": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+ "dev": true
+ },
+ "import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "internal-slot": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
+ "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==",
+ "dev": true,
+ "requires": {
+ "get-intrinsic": "^1.2.0",
+ "has": "^1.0.3",
+ "side-channel": "^1.0.4"
+ }
+ },
+ "is-array-buffer": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
+ "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.0",
+ "is-typed-array": "^1.1.10"
+ }
+ },
+ "is-bigint": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "dev": true,
+ "requires": {
+ "has-bigints": "^1.0.1"
+ }
+ },
+ "is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true
+ },
+ "is-core-module": {
+ "version": "2.13.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz",
+ "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-date-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+ "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-negative-zero": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+ "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+ "dev": true
+ },
+ "is-number-object": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+ "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true
+ },
+ "is-regex": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+ "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-shared-array-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
+ "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2"
+ }
+ },
+ "is-string": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+ "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "dev": true,
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-symbol": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+ "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.2"
+ }
+ },
+ "is-typed-array": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
+ "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
+ "dev": true,
+ "requires": {
+ "which-typed-array": "^1.1.11"
+ }
+ },
+ "is-weakref": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+ "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2"
+ }
+ },
+ "isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "requires": {
+ "argparse": "^2.0.1"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true
+ },
+ "json5": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ },
+ "levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ }
+ },
+ "locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^5.0.0"
+ }
+ },
+ "lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "object-inspect": {
+ "version": "1.12.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
+ "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
+ "dev": true
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true
+ },
+ "object.assign": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
+ "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "has-symbols": "^1.0.3",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "object.fromentries": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz",
+ "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ }
+ },
+ "object.groupby": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.0.tgz",
+ "integrity": "sha512-70MWG6NfRH9GnbZOikuhPPYzpUpof9iW2J9E4dW7FXTqPNb6rllE6u39SKwwiNh8lCwX3DDb5OgcKGiEBrTTyw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.21.2",
+ "get-intrinsic": "^1.2.1"
+ }
+ },
+ "object.values": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz",
+ "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "optionator": {
+ "version": "0.9.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
+ "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
+ "dev": true,
+ "requires": {
+ "@aashutoshrathi/word-wrap": "^1.2.3",
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0"
+ }
+ },
+ "p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "requires": {
+ "yocto-queue": "^0.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^3.0.2"
+ }
+ },
+ "parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0"
+ }
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true
+ },
+ "punycode": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+ "dev": true
+ },
+ "queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true
+ },
+ "regexp.prototype.flags": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz",
+ "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "functions-have-names": "^1.2.3"
+ }
+ },
+ "regexpp": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
+ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.22.4",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz",
+ "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true
+ },
+ "reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "requires": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "safe-array-concat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz",
+ "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.0",
+ "has-symbols": "^1.0.3",
+ "isarray": "^2.0.5"
+ }
+ },
+ "safe-regex-test": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
+ "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.3",
+ "is-regex": "^1.1.4"
+ }
+ },
+ "semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ }
+ },
+ "string.prototype.trim": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz",
+ "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ }
+ },
+ "string.prototype.trimend": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz",
+ "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ }
+ },
+ "string.prototype.trimstart": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz",
+ "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true
+ },
+ "tsconfig-paths": {
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz",
+ "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==",
+ "dev": true,
+ "requires": {
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.2",
+ "minimist": "^1.2.6",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "^1.2.1"
+ }
+ },
+ "type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true
+ },
+ "typed-array-buffer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz",
+ "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.1",
+ "is-typed-array": "^1.1.10"
+ }
+ },
+ "typed-array-byte-length": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz",
+ "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "has-proto": "^1.0.1",
+ "is-typed-array": "^1.1.10"
+ }
+ },
+ "typed-array-byte-offset": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz",
+ "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==",
+ "dev": true,
+ "requires": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "has-proto": "^1.0.1",
+ "is-typed-array": "^1.1.10"
+ }
+ },
+ "typed-array-length": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
+ "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "is-typed-array": "^1.1.9"
+ }
+ },
+ "unbox-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+ "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.0.3",
+ "which-boxed-primitive": "^1.0.2"
+ }
+ },
+ "uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "which-boxed-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+ "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+ "dev": true,
+ "requires": {
+ "is-bigint": "^1.0.1",
+ "is-boolean-object": "^1.1.0",
+ "is-number-object": "^1.0.4",
+ "is-string": "^1.0.5",
+ "is-symbol": "^1.0.3"
+ }
+ },
+ "which-typed-array": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
+ "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==",
+ "dev": true,
+ "requires": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true
+ }
+ }
+}
diff --git a/package.json b/package.json
index 49b98773f..0e9c95ac9 100644
--- a/package.json
+++ b/package.json
@@ -1,55 +1,52 @@
{
"name": "cordova-plugin-media",
- "version": "2.4.1-dev",
+ "version": "7.0.1-dev",
"description": "Cordova Media Plugin",
+ "types": "./types/index.d.ts",
"cordova": {
"id": "cordova-plugin-media",
"platforms": [
"android",
- "amazon-fireos",
- "ubuntu",
- "ios",
- "blackberry10",
- "wp7",
- "wp8",
- "windows8",
- "windows",
- "tizen"
+ "browser",
+ "ios"
]
},
- "repository": {
- "type": "git",
- "url": "https://github.com/apache/cordova-plugin-media"
- },
+ "repository": "github:apache/cordova-plugin-media",
+ "bugs": "https://github.com/apache/cordova-plugin-media/issues",
"keywords": [
"cordova",
"media",
"ecosystem:cordova",
"cordova-android",
- "cordova-amazon-fireos",
- "cordova-ubuntu",
- "cordova-ios",
- "cordova-blackberry10",
- "cordova-wp7",
- "cordova-wp8",
- "cordova-windows8",
- "cordova-windows",
- "cordova-tizen"
+ "cordova-browser",
+ "cordova-ios"
],
"scripts": {
- "test": "npm run jshint",
- "jshint": "jshint www && jshint src && jshint tests"
+ "test": "npm run lint",
+ "lint": "eslint ."
},
"author": "Apache Software Foundation",
"license": "Apache-2.0",
"engines": {
"cordovaDependencies": {
"3.0.0": {
+ "cordova-android": ">=6.1.0"
+ },
+ "4.0.0": {
+ "cordova-android": ">=6.3.0"
+ },
+ "6.0.0": {
+ "cordova-android": ">=10.0.0"
+ },
+ "7.0.0": {
+ "cordova-android": ">=12.0.0"
+ },
+ "8.0.0": {
"cordova": ">100"
}
}
},
"devDependencies": {
- "jshint": "^2.6.0"
+ "@cordova/eslint-config": "^5.0.0"
}
}
diff --git a/plugin.xml b/plugin.xml
index 951d30107..e8df8bcb8 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -19,19 +19,22 @@
-->
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ id="cordova-plugin-media"
+ version="7.0.1-dev">
Media
Cordova Media Plugin
Apache 2.0
cordova,media
- https://git-wip-us.apache.org/repos/asf/cordova-plugin-media.git
- https://issues.apache.org/jira/browse/CB/component/12320647
+ https://github.com/apache/cordova-plugin-media
+ https://github.com/apache/cordova-plugin-media/issues
-
-
+
+
+
+
+
@@ -52,129 +55,26 @@ id="cordova-plugin-media"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/src/android/AudioHandler.java b/src/android/AudioHandler.java
index 48211ad42..51a0bdf0f 100644
--- a/src/android/AudioHandler.java
+++ b/src/android/AudioHandler.java
@@ -31,7 +31,6 @@ Licensed to the Apache Software Foundation (ASF) under one
import android.net.Uri;
import android.os.Build;
-import java.security.Permission;
import java.util.ArrayList;
import org.apache.cordova.LOG;
@@ -62,8 +61,7 @@ public class AudioHandler extends CordovaPlugin {
private int origVolumeStream = -1;
private CallbackContext messageChannel;
-
- public static String [] permissions = { Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE};
+ // Permission Request Codes
public static int RECORD_AUDIO = 0;
public static int WRITE_EXTERNAL_STORAGE = 1;
@@ -81,16 +79,8 @@ public AudioHandler() {
this.pausedForFocus = new ArrayList();
}
-
- protected void getWritePermission(int requestCode)
- {
- PermissionHelper.requestPermission(this, requestCode, permissions[WRITE_EXTERNAL_STORAGE]);
- }
-
-
- protected void getMicPermission(int requestCode)
- {
- PermissionHelper.requestPermission(this, requestCode, permissions[RECORD_AUDIO]);
+ public Context getApplicationContext() {
+ return cordova.getActivity().getApplicationContext();
}
@@ -179,6 +169,10 @@ else if (action.equals("messageChannel")) {
callbackContext.sendPluginResult(new PluginResult(status, f));
return true;
}
+ else if (action.equals("setRate")) {
+ this.setRate(args.getString(0), Float.parseFloat(args.getString(1)));
+ return true;
+ }
else { // Unrecognized action.
return false;
}
@@ -411,7 +405,7 @@ public void pauseAllLostFocus() {
public void resumeAllGainedFocus() {
for (AudioPlayer audio : this.pausedForFocus) {
- audio.startPlaying(null);
+ audio.resumePlaying();
}
this.pausedForFocus.clear();
}
@@ -487,6 +481,23 @@ public void setVolume(String id, float volume) {
}
}
+ /**
+ * Set the playback rate of an audio file
+ *
+ * @param id The id of the audio player
+ * @param rate The playback rate
+ */
+ public void setRate(String id, float rate) {
+ String TAG3 = "AudioHandler.setRate(): Error : ";
+ AudioPlayer audio = this.players.get(id);
+ if (audio != null) {
+ audio.setRate(rate);
+ } else {
+ LOG.e(TAG3, "Unknown Audio Player " + id);
+ }
+ }
+
+
private void onFirstPlayerCreated() {
origVolumeStream = cordova.getActivity().getVolumeControlStream();
cordova.getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC);
@@ -538,19 +549,22 @@ public void onRequestPermissionResult(int requestCode, String[] permissions,
private void promptForRecord()
{
- if(PermissionHelper.hasPermission(this, permissions[WRITE_EXTERNAL_STORAGE]) &&
- PermissionHelper.hasPermission(this, permissions[RECORD_AUDIO])) {
- this.startRecordingAudio(recordId, FileHelper.stripFileProtocol(fileUriStr));
- }
- else if(PermissionHelper.hasPermission(this, permissions[RECORD_AUDIO]))
- {
- getWritePermission(WRITE_EXTERNAL_STORAGE);
+ // If Android < 33, check for WRITE_EXTERNAL_STORAGE permission
+ if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
+ if (!PermissionHelper.hasPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
+ PermissionHelper.requestPermission(this, WRITE_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE);
+ return;
+ }
}
- else
- {
- getMicPermission(RECORD_AUDIO);
+
+ // For all Android versions, check for RECORD_AUDIO permission
+ if (!PermissionHelper.hasPermission(this, Manifest.permission.RECORD_AUDIO)) {
+ PermissionHelper.requestPermission(this, RECORD_AUDIO, Manifest.permission.RECORD_AUDIO);
+ return;
}
+ // Start recording if all necessary permissions were granted.
+ this.startRecordingAudio(recordId, FileHelper.stripFileProtocol(fileUriStr));
}
/**
diff --git a/src/android/AudioPlayer.java b/src/android/AudioPlayer.java
index 171cde9f7..c47917730 100644
--- a/src/android/AudioPlayer.java
+++ b/src/android/AudioPlayer.java
@@ -18,6 +18,7 @@ Licensed to the Apache Software Foundation (ASF) under one
*/
package org.apache.cordova.media;
+import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
@@ -25,6 +26,7 @@ Licensed to the Apache Software Foundation (ASF) under one
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaRecorder;
import android.os.Environment;
+import android.os.Build;
import org.apache.cordova.LOG;
@@ -78,6 +80,7 @@ public enum STATE { MEDIA_NONE,
// private static int MEDIA_ERR_NONE_SUPPORTED = 4;
private AudioHandler handler; // The AudioHandler object
+ private Context context; // The Application Context object
private String id; // The id of this player (used to identify Media object in JavaScript)
private MODE mode = MODE.NONE; // Playback or Recording mode
private STATE state = STATE.MEDIA_NONE; // State of recording or playback
@@ -92,6 +95,7 @@ public enum STATE { MEDIA_NONE,
private MediaPlayer player = null; // Audio player object
private boolean prepareOnly = true; // playback after file prepare flag
private int seekOnPrepared = 0; // seek to this location once media is prepared
+ private float setRateOnPrepared = -1;
/**
* Constructor.
@@ -101,19 +105,29 @@ public enum STATE { MEDIA_NONE,
*/
public AudioPlayer(AudioHandler handler, String id, String file) {
this.handler = handler;
+ context = handler.getApplicationContext();
this.id = id;
this.audioFile = file;
this.tempFiles = new LinkedList();
+
}
- private String generateTempFile() {
- String tempFileName = null;
- if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- tempFileName = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tmprecording-" + System.currentTimeMillis() + ".3gp";
- } else {
- tempFileName = "/data/data/" + handler.cordova.getActivity().getPackageName() + "/cache/tmprecording-" + System.currentTimeMillis() + ".3gp";
- }
- return tempFileName;
+ /**
+ * Creates an audio file path from the provided fileName or creates a new temporary file path.
+ *
+ * @param fileName the audio file name, if null a temporary 3gp file name is provided
+ * @return String
+ */
+ private String createAudioFilePath(String fileName) {
+ File dir = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
+ ? context.getExternalFilesDir(null)
+ : context.getCacheDir();
+
+ fileName = (fileName == null || fileName.isEmpty())
+ ? String.format("tmprecording-%d.3gp", System.currentTimeMillis())
+ : fileName;
+
+ return dir.getAbsolutePath() + File.separator + fileName;
}
/**
@@ -130,7 +144,9 @@ public void destroy() {
this.player = null;
}
if (this.recorder != null) {
- this.stopRecording(true);
+ if (this.state != STATE.MEDIA_STOPPED) {
+ this.stopRecording(true);
+ }
this.recorder.release();
this.recorder = null;
}
@@ -142,18 +158,21 @@ public void destroy() {
* @param file The name of the file
*/
public void startRecording(String file) {
+ String errorMessage;
switch (this.mode) {
case PLAY:
- LOG.d(LOG_TAG, "AudioPlayer Error: Can't record in play mode.");
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ errorMessage = "AudioPlayer Error: Can't record in play mode.";
+ sendErrorStatus(MEDIA_ERR_ABORTED, errorMessage);
break;
case NONE:
this.audioFile = file;
this.recorder = new MediaRecorder();
this.recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
- this.recorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR); // THREE_GPP);
- this.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //AMR_NB);
- this.tempFile = generateTempFile();
+ this.recorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS); // RAW_AMR);
+ this.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); //AMR_NB);
+ this.recorder.setAudioEncodingBitRate(96000);
+ this.recorder.setAudioSamplingRate(44100);
+ this.tempFile = createAudioFilePath(null);
this.recorder.setOutputFile(this.tempFile);
try {
this.recorder.prepare();
@@ -166,11 +185,11 @@ public void startRecording(String file) {
e.printStackTrace();
}
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ sendErrorStatus(MEDIA_ERR_ABORTED, null);
break;
case RECORD:
- LOG.d(LOG_TAG, "AudioPlayer Error: Already recording.");
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ errorMessage = "AudioPlayer Error: Already recording.";
+ sendErrorStatus(MEDIA_ERR_ABORTED, errorMessage);
}
}
@@ -183,11 +202,7 @@ public void moveFile(String file) {
/* this is a hack to save the file as the specified name */
if (!file.startsWith("/")) {
- if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- file = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + file;
- } else {
- file = "/data/data/" + handler.cordova.getActivity().getPackageName() + "/cache/" + file;
- }
+ file = createAudioFilePath(file);
}
int size = this.tempFiles.size();
@@ -197,8 +212,44 @@ public void moveFile(String file) {
if (size == 1) {
String logMsg = "renaming " + this.tempFile + " to " + file;
LOG.d(LOG_TAG, logMsg);
+
File f = new File(this.tempFile);
- if (!f.renameTo(new File(file))) LOG.e(LOG_TAG, "FAILED " + logMsg);
+ if (!f.renameTo(new File(file))) {
+
+ FileOutputStream outputStream = null;
+ File outputFile = null;
+ try {
+ outputFile = new File(file);
+ outputStream = new FileOutputStream(outputFile);
+ FileInputStream inputStream = null;
+ File inputFile = null;
+ try {
+ inputFile = new File(this.tempFile);
+ LOG.d(LOG_TAG, "INPUT FILE LENGTH: " + String.valueOf(inputFile.length()) );
+ inputStream = new FileInputStream(inputFile);
+ copy(inputStream, outputStream, false);
+ } catch (Exception e) {
+ LOG.e(LOG_TAG, e.getLocalizedMessage(), e);
+ } finally {
+ if (inputStream != null) try {
+ inputStream.close();
+ inputFile.delete();
+ inputFile = null;
+ } catch (Exception e) {
+ LOG.e(LOG_TAG, e.getLocalizedMessage(), e);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (outputStream != null) try {
+ outputStream.close();
+ LOG.d(LOG_TAG, "OUTPUT FILE LENGTH: " + String.valueOf(outputFile.length()) );
+ } catch (Exception e) {
+ LOG.e(LOG_TAG, e.getLocalizedMessage(), e);
+ }
+ }
+ }
}
// more than one file so the user must have pause recording. We'll need to concat files.
else {
@@ -264,13 +315,16 @@ public void stopRecording(boolean stop) {
this.recorder.stop();
}
this.recorder.reset();
- this.tempFiles.add(this.tempFile);
+ if (!this.tempFiles.contains(this.tempFile)) {
+ this.tempFiles.add(this.tempFile);
+ }
if (stop) {
LOG.d(LOG_TAG, "stopping recording");
this.setState(STATE.MEDIA_STOPPED);
this.moveFile(this.audioFile);
} else {
LOG.d(LOG_TAG, "pause recording");
+ this.setState(STATE.MEDIA_PAUSED);
}
}
catch (Exception e) {
@@ -314,7 +368,7 @@ public void seekToPlaying(int milliseconds) {
this.player.seekTo(milliseconds);
}
LOG.d(LOG_TAG, "Send a onStatus update for the new seek");
- sendStatusChange(MEDIA_POSITION, null, (milliseconds / 1000.0f));
+ sendStatusChange(MEDIA_POSITION, null, (milliseconds / 1000.0f), null);
}
else {
this.seekOnPrepared = milliseconds;
@@ -332,8 +386,8 @@ public void pausePlaying() {
this.setState(STATE.MEDIA_PAUSED);
}
else {
- LOG.d(LOG_TAG, "AudioPlayer Error: pausePlaying() called during invalid state: " + this.state.ordinal());
- sendErrorStatus(MEDIA_ERR_NONE_ACTIVE);
+ String errorMessage = "AudioPlayer Error: pausePlaying() called during invalid state: " + this.state.ordinal();
+ sendErrorStatus(MEDIA_ERR_NONE_ACTIVE, errorMessage);
}
}
@@ -348,11 +402,18 @@ public void stopPlaying() {
this.setState(STATE.MEDIA_STOPPED);
}
else {
- LOG.d(LOG_TAG, "AudioPlayer Error: stopPlaying() called during invalid state: " + this.state.ordinal());
- sendErrorStatus(MEDIA_ERR_NONE_ACTIVE);
+ String errorMessage = "AudioPlayer Error: stopPlaying() called during invalid state: " + this.state.ordinal();
+ sendErrorStatus(MEDIA_ERR_NONE_ACTIVE, errorMessage);
}
}
+ /**
+ * Resume playing.
+ */
+ public void resumePlaying() {
+ this.startPlaying(this.audioFile);
+ }
+
/**
* Callback to be invoked when playback of a media source has completed.
*
@@ -371,7 +432,7 @@ public void onCompletion(MediaPlayer player) {
public long getCurrentPosition() {
if ((this.state == STATE.MEDIA_RUNNING) || (this.state == STATE.MEDIA_PAUSED)) {
int curPos = this.player.getCurrentPosition();
- sendStatusChange(MEDIA_POSITION, null, (curPos / 1000.0f));
+ sendStatusChange(MEDIA_POSITION, null, (curPos / 1000.0f), null);
return curPos;
}
else {
@@ -436,6 +497,9 @@ public void onPrepared(MediaPlayer player) {
this.player.setOnCompletionListener(this);
// seek to any location received while not prepared
this.seekToPlaying(this.seekOnPrepared);
+ // apply any playback rate received while not prepared
+ if (setRateOnPrepared >= 0)
+ this.player.setPlaybackParams (this.player.getPlaybackParams().setSpeed(setRateOnPrepared));
// If start playing after prepared
if (!this.prepareOnly) {
this.player.start();
@@ -450,7 +514,7 @@ public void onPrepared(MediaPlayer player) {
this.prepareOnly = true;
// Send status notification to JavaScript
- sendStatusChange(MEDIA_DURATION, null, this.duration);
+ sendStatusChange(MEDIA_DURATION, null, this.duration, null);
}
/**
@@ -471,14 +535,14 @@ private float getDurationInSeconds() {
* @param arg2 an extra code, specific to the error.
*/
public boolean onError(MediaPlayer player, int arg1, int arg2) {
- LOG.d(LOG_TAG, "AudioPlayer.onError(" + arg1 + ", " + arg2 + ")");
+ String errorMessage = "AudioPlayer.onError(" + arg1 + ", " + arg2 + ")";
// we don't want to send success callback
// so we don't call setState() here
this.state = STATE.MEDIA_STOPPED;
this.destroy();
// Send error notification to JavaScript
- sendErrorStatus(arg1);
+ sendErrorStatus(arg1, errorMessage);
return false;
}
@@ -490,7 +554,7 @@ public boolean onError(MediaPlayer player, int arg1, int arg2) {
*/
private void setState(STATE state) {
if (this.state != state) {
- sendStatusChange(MEDIA_STATE, null, (float)state.ordinal());
+ sendStatusChange(MEDIA_STATE, null, (float)state.ordinal(), null);
}
this.state = state;
}
@@ -526,8 +590,8 @@ public void setVolume(float volume) {
if (this.player != null) {
this.player.setVolume(volume, volume);
} else {
- LOG.d(LOG_TAG, "AudioPlayer Error: Cannot set volume until the audio file is initialized.");
- sendErrorStatus(MEDIA_ERR_NONE_ACTIVE);
+ String errorMessage = "AudioPlayer Error: Cannot set volume until the audio file is initialized.";
+ sendErrorStatus(MEDIA_ERR_NONE_ACTIVE, errorMessage);
}
}
@@ -543,8 +607,8 @@ private boolean playMode() {
case PLAY:
break;
case RECORD:
- LOG.d(LOG_TAG, "AudioPlayer Error: Can't play in record mode.");
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ String errorMessage = "AudioPlayer Error: Can't play in record mode.";
+ sendErrorStatus(MEDIA_ERR_ABORTED, errorMessage);
return false; //player is not ready
}
return true;
@@ -566,7 +630,7 @@ private boolean readyPlayer(String file) {
try {
this.loadAudioFile(file);
} catch (Exception e) {
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ sendErrorStatus(MEDIA_ERR_ABORTED, e.getMessage());
}
return false;
case MEDIA_LOADING:
@@ -580,9 +644,9 @@ private boolean readyPlayer(String file) {
return true;
case MEDIA_STOPPED:
//if we are readying the same file
- if (this.audioFile.compareTo(file) == 0) {
+ if (file!=null && this.audioFile.compareTo(file) == 0) {
//maybe it was recording?
- if(this.recorder!=null && player==null) {
+ if (player == null) {
this.player = new MediaPlayer();
this.player.setOnErrorListener(this);
this.prepareOnly = false;
@@ -590,7 +654,7 @@ private boolean readyPlayer(String file) {
try {
this.loadAudioFile(file);
} catch (Exception e) {
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ sendErrorStatus(MEDIA_ERR_ABORTED, e.getMessage());
}
return false;//we´re not ready yet
}
@@ -606,14 +670,14 @@ private boolean readyPlayer(String file) {
try {
this.loadAudioFile(file);
} catch (Exception e) {
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ sendErrorStatus(MEDIA_ERR_ABORTED, e.getMessage());
}
//if we had to prepare the file, we won't be in the correct state for playback
return false;
}
default:
- LOG.d(LOG_TAG, "AudioPlayer Error: startPlaying() called during invalid state: " + this.state);
- sendErrorStatus(MEDIA_ERR_ABORTED);
+ String errorMessage = "AudioPlayer Error: startPlaying() called during invalid state: " + this.state;
+ sendErrorStatus(MEDIA_ERR_ABORTED, errorMessage);
}
}
return false;
@@ -650,7 +714,7 @@ private void loadAudioFile(String file) throws IllegalArgumentException, Securit
fileInputStream.close();
}
else {
- this.player.setDataSource(Environment.getExternalStorageDirectory().getPath() + "/" + file);
+ this.player.setDataSource(createAudioFilePath(file));
}
}
this.setState(STATE.MEDIA_STARTING);
@@ -662,16 +726,19 @@ private void loadAudioFile(String file) throws IllegalArgumentException, Securit
}
}
- private void sendErrorStatus(int errorCode) {
- sendStatusChange(MEDIA_ERROR, errorCode, null);
+ private void sendErrorStatus(int errorCode, String errorMessage) {
+ sendStatusChange(MEDIA_ERROR, errorCode, null, errorMessage);
}
- private void sendStatusChange(int messageType, Integer additionalCode, Float value) {
-
+ private void sendStatusChange(int messageType, Integer additionalCode, Float value, String errorMessage) {
if (additionalCode != null && value != null) {
throw new IllegalArgumentException("Only one of additionalCode or value can be specified, not both");
}
+ if (errorMessage != null) {
+ LOG.d(LOG_TAG, errorMessage);
+ }
+
JSONObject statusDetails = new JSONObject();
try {
statusDetails.put("id", this.id);
@@ -679,6 +746,11 @@ private void sendStatusChange(int messageType, Integer additionalCode, Float val
if (additionalCode != null) {
JSONObject code = new JSONObject();
code.put("code", additionalCode.intValue());
+
+ if (errorMessage != null) {
+ code.put("message", errorMessage);
+ }
+
statusDetails.put("value", code);
}
else if (value != null) {
@@ -709,4 +781,32 @@ public float getCurrentAmplitude() {
}
return 0;
}
+
+ /**
+ * Set the playback rate for the player (ignored on API < 23)
+ *
+ * @param volume
+ */
+ public void setRate(float rate) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+ LOG.d(LOG_TAG, "AudioPlayer Warning: Request to set playback rate not supported on current OS version");
+ return;
+ }
+
+ if (this.player != null) {
+ try {
+ boolean wasPlaying = this.player.isPlaying();
+
+ this.player.setPlaybackParams(this.player.getPlaybackParams().setSpeed(rate));
+
+ if (!wasPlaying && this.player.isPlaying()) {
+ this.player.pause();
+ }
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ } else {
+ setRateOnPrepared = rate;
+ }
+ }
}
diff --git a/src/blackberry10/index.js b/src/blackberry10/index.js
deleted file mode 100644
index e48fafa37..000000000
--- a/src/blackberry10/index.js
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/* global qnx, PluginResult */
-
-var audioObjects = {},
- mediaErrorsHandled = false;
-
-// There is a bug in the webplatform handling of media error
-// dialogs prior to 10.2. This function needs to be run once
-// on the webview which plays audio to prevent freezing.
-function handleMediaErrors() {
- var webview = qnx.webplatform.getWebViews()[0],
- handler = webview.onDialogRequested;
- if (!mediaErrorsHandled) {
- webview.allowWebEvent("DialogRequested");
- webview.onDialogRequested = undefined;
- webview.onDialogRequested = function (eventArgs) {
- var parsedArgs = JSON.parse(eventArgs);
- if (parsedArgs.dialogType === 'MediaError') {
- return '{"setPreventDefault": true}';
- }
- handler(eventArgs);
- };
- mediaErrorsHandled = true;
- }
-}
-
-module.exports = {
-
- create: function (success, fail, args, env) {
- var result = new PluginResult(args, env),
- id;
-
- if (!args[0]) {
- result.error("Media Object id was not sent in arguments");
- return;
- }
-
- id = JSON.parse(decodeURIComponent(args[0]));
-
- if (!args[1]){
- audioObjects[id] = new Audio();
- } else {
- audioObjects[id] = new Audio(JSON.parse(decodeURIComponent(args[1])));
- }
-
- handleMediaErrors();
-
- result.ok();
- },
-
- startPlayingAudio: function (success, fail, args, env) {
-
- var audio,
- id,
- result = new PluginResult(args, env);
-
- if (!args[0]) {
- result.error("Media Object id was not sent in arguments");
- return;
- }
-
- id = JSON.parse(decodeURIComponent(args[0]));
-
- audio = audioObjects[id];
-
- if (!audio) {
- result.error("Audio object has not been initialized");
- } else {
- audio.play();
- result.ok();
- }
- },
-
- stopPlayingAudio: function (success, fail, args, env) {
-
- var audio,
- id,
- result = new PluginResult(args, env);
-
- if (!args[0]) {
- result.error("Media Object id was not sent in arguments");
- return;
- }
-
- id = JSON.parse(decodeURIComponent(args[0]));
-
- audio = audioObjects[id];
-
- if (!audio) {
- result.error("Audio Object has not been initialized");
- return;
- }
-
- audio.pause();
- audio.currentTime = 0;
-
- result.ok();
- },
-
- seekToAudio: function (success, fail, args, env) {
-
- var audio,
- result = new PluginResult(args, env);
-
- if (!args[0]) {
- result.error("Media Object id was not sent in arguments");
- return;
- }
-
- audio = audioObjects[JSON.parse(decodeURIComponent(args[0]))];
-
- if (!audio) {
- result.error("Audio Object has not been initialized");
- } else if (!args[1]) {
- result.error("Media seek time argument not found");
- } else {
- try {
- audio.currentTime = JSON.parse(decodeURIComponent(args[1])) / 1000;
- result.ok();
- } catch (e) {
- result.error("Error seeking audio: " + e);
- }
- }
- },
-
- pausePlayingAudio: function (success, fail, args, env) {
-
- var audio,
- result = new PluginResult(args, env);
-
- if (!args[0]) {
- result.error("Media Object id was not sent in arguments");
- return;
- }
-
- audio = audioObjects[JSON.parse(decodeURIComponent(args[0]))];
-
- if (!audio) {
- result.error("Audio Object has not been initialized");
- return;
- }
-
- audio.pause();
- },
-
- getCurrentPositionAudio: function (success, fail, args, env) {
-
- var audio,
- result = new PluginResult(args, env);
-
- if (!args[0]) {
- result.error("Media Object id was not sent in arguments");
- return;
- }
-
- audio = audioObjects[JSON.parse(decodeURIComponent(args[0]))];
-
- if (!audio) {
- result.error("Audio Object has not been initialized");
- return;
- }
-
- result.ok(audio.currentTime);
- },
-
- getDuration: function (success, fail, args, env) {
-
- var audio,
- result = new PluginResult(args, env);
-
- if (!args[0]) {
- result.error("Media Object id was not sent in arguments");
- return;
- }
-
- audio = audioObjects[JSON.parse(decodeURIComponent(args[0]))];
-
- if (!audio) {
- result.error("Audio Object has not been initialized");
- return;
- }
-
- result.ok(audio.duration);
- },
-
- startRecordingAudio: function (success, fail, args, env) {
- var result = new PluginResult(args, env);
- result.error("Not supported");
- },
-
- stopRecordingAudio: function (success, fail, args, env) {
- var result = new PluginResult(args, env);
- result.error("Not supported");
- },
-
- release: function (success, fail, args, env) {
- var audio,
- id,
- result = new PluginResult(args, env);
-
- if (!args[0]) {
- result.error("Media Object id was not sent in arguments");
- return;
- }
-
- id = JSON.parse(decodeURIComponent(args[0]));
-
- audio = audioObjects[id];
-
- if (audio) {
- if(audio.src !== ""){
- audio.src = undefined;
- }
- audioObjects[id] = undefined;
- }
-
- result.ok();
- }
-};
diff --git a/src/ios/CDVSound.h b/src/ios/CDVSound.h
index 3f123b03c..786e51148 100644
--- a/src/ios/CDVSound.h
+++ b/src/ios/CDVSound.h
@@ -15,6 +15,7 @@
under the License.
*/
+@import WebKit;
#import
#import
#import
@@ -87,10 +88,12 @@ typedef NSUInteger CDVMediaMsg;
NSString* currMediaId;
AVAudioSession* avSession;
AVPlayer* avPlayer;
+ NSString* statusCallbackId;
}
@property (nonatomic, strong) NSMutableDictionary* soundCache;
@property (nonatomic, strong) AVAudioSession* avSession;
@property (nonatomic, strong) NSString* currMediaId;
+@property (nonatomic, strong) NSString* statusCallbackId;
- (void)startPlayingAudio:(CDVInvokedUrlCommand*)command;
- (void)pausePlayingAudio:(CDVInvokedUrlCommand*)command;
@@ -110,7 +113,7 @@ typedef NSUInteger CDVMediaMsg;
- (CDVAudioFile*)audioFileForResource:(NSString*)resourcePath withId:(NSString*)mediaId doValidation:(BOOL)bValidate forRecording:(BOOL)bRecord;
- (CDVAudioFile*)audioFileForResource:(NSString*)resourcePath withId:(NSString*)mediaId doValidation:(BOOL)bValidate forRecording:(BOOL)bRecord suppressValidationErrors:(BOOL)bSuppress;
- (BOOL)prepareToPlay:(CDVAudioFile*)audioFile withId:(NSString*)mediaId;
-- (NSString*)createMediaErrorWithCode:(CDVMediaError)code message:(NSString*)message;
+- (NSDictionary*)createMediaErrorWithCode:(CDVMediaError)code message:(NSString*)message;
- (void)startRecordingAudio:(CDVInvokedUrlCommand*)command;
- (void)stopRecordingAudio:(CDVInvokedUrlCommand*)command;
diff --git a/src/ios/CDVSound.m b/src/ios/CDVSound.m
index 09d3587fb..30f257687 100644
--- a/src/ios/CDVSound.m
+++ b/src/ios/CDVSound.m
@@ -24,11 +24,27 @@ Licensed to the Apache Software Foundation (ASF) under one
#define HTTP_SCHEME_PREFIX @"http://"
#define HTTPS_SCHEME_PREFIX @"https://"
#define CDVFILE_PREFIX @"cdvfile://"
-#define RECORDING_WAV @"wav"
+#define FILE_PREFIX @"file://"
@implementation CDVSound
-@synthesize soundCache, avSession, currMediaId;
+BOOL keepAvAudioSessionAlwaysActive = NO;
+
+@synthesize soundCache, avSession, currMediaId, statusCallbackId;
+
+-(void) pluginInitialize
+{
+ NSDictionary* settings = self.commandDelegate.settings;
+ keepAvAudioSessionAlwaysActive = [[settings objectForKey:[@"KeepAVAudioSessionAlwaysActive" lowercaseString]] boolValue];
+ if (keepAvAudioSessionAlwaysActive) {
+ if ([self hasAudioSession]) {
+ NSError* error = nil;
+ if(![self.avSession setActive:YES error:&error]) {
+ NSLog(@"Unable to activate session: %@", [error localizedFailureReason]);
+ }
+ }
+ }
+}
// Maps a url for a resource path for recording
- (NSURL*)urlForRecording:(NSString*)resourcePath
@@ -38,9 +54,11 @@ - (NSURL*)urlForRecording:(NSString*)resourcePath
NSString* docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
// first check for correct extension
- if ([[resourcePath pathExtension] caseInsensitiveCompare:RECORDING_WAV] != NSOrderedSame) {
+ NSString* ext=[resourcePath pathExtension];
+ if ([ext caseInsensitiveCompare:@"wav"] != NSOrderedSame &&
+ [ext caseInsensitiveCompare:@"m4a"] != NSOrderedSame) {
resourceURL = nil;
- NSLog(@"Resource for recording must have %@ extension", RECORDING_WAV);
+ NSLog(@"Resource for recording must have wav or m4a extension");
} else if ([resourcePath hasPrefix:DOCUMENTS_SCHEME_PREFIX]) {
// try to find Documents:// resources
filePath = [resourcePath stringByReplacingOccurrencesOfString:DOCUMENTS_SCHEME_PREFIX withString:[NSString stringWithFormat:@"%@/", docsPath]];
@@ -53,6 +71,9 @@ - (NSURL*)urlForRecording:(NSString*)resourcePath
resourceURL = [NSURL URLWithString:resourcePath];
}
} else {
+ if ([resourcePath hasPrefix:FILE_PREFIX]) { // Support file scheme
+ resourcePath = [resourcePath substringFromIndex:[FILE_PREFIX length]];
+ }
// if resourcePath is not from FileSystem put in tmp dir, else attempt to use provided resource path
NSString* tmpPath = [NSTemporaryDirectory()stringByStandardizingPath];
BOOL isTmp = [resourcePath rangeOfString:tmpPath].location != NSNotFound;
@@ -72,6 +93,67 @@ - (NSURL*)urlForRecording:(NSString*)resourcePath
return resourceURL;
}
+- (NSString*)getCdvCustomSchemeAssetPrefix {
+ NSDictionary* settings = self.commandDelegate.settings;
+ NSString *scheme = [settings objectForKey:[@"scheme" lowercaseString]];
+ // If scheme is file or nil, then default to file scheme
+ Boolean isCdvFileScheme = [scheme isEqualToString: @"file"] || scheme == nil;
+ NSString *hostname = @"";
+
+ if (!isCdvFileScheme) {
+ if (scheme == nil || [WKWebView handlesURLScheme:scheme]) {
+ scheme = @"app";
+ }
+
+ hostname = [settings objectForKey:[@"hostname" lowercaseString]];
+ if(hostname == nil){
+ hostname = @"localhost";
+ }
+
+ return [NSString stringWithFormat:@"%@://%@/", scheme, hostname];
+ }
+
+ return nil;
+}
+
+- (Boolean)isCdvCustomSchemeUrl:(NSString*)resourcePath
+{
+ NSString *assetUrl = [self getCdvCustomSchemeAssetPrefix];
+
+ if (assetUrl != nil) {
+ return [resourcePath hasPrefix:assetUrl];
+ }
+
+ return false;
+}
+
+// Attempts to find the file path in the "www" or "LocalFileSystem.TEMPORARY" directory.
+// Used for "file://" & "custom-scheme://hostname/" schemes and leading "/" directory paths.
+- (NSString*)attemptFindFilePath:(NSString*)resourcePath prefix:(NSString*)prefix
+{
+ resourcePath = [resourcePath substringFromIndex:[prefix length]];
+
+ NSString *filePath = [self.commandDelegate pathForResource:resourcePath];
+
+ if (filePath == nil) {
+ // see if this exists in the documents/temp directory from a previous recording
+ NSString* testPath = [NSString stringWithFormat:@"%@/%@", [NSTemporaryDirectory()stringByStandardizingPath], resourcePath];
+ if ([[NSFileManager defaultManager] fileExistsAtPath:testPath]) {
+ // inefficient as existence will be checked again below but only way to determine if file exists from previous recording
+ filePath = testPath;
+ NSLog(@"Will attempt to use file resource from LocalFileSystem.TEMPORARY directory");
+ } else {
+ // attempt to use path provided
+ filePath = resourcePath;
+ NSLog(@"Will attempt to use file resource '%@'", filePath);
+ }
+ } else {
+ NSLog(@"Found resource '%@' in the web folder.", filePath);
+ }
+
+ return filePath;
+}
+
// Maps a url for a resource path for playing
// "Naked" resource paths are assumed to be from the www folder as its base
- (NSURL*)urlForPlaying:(NSString*)resourcePath
@@ -79,8 +161,15 @@ - (NSURL*)urlForPlaying:(NSString*)resourcePath
NSURL* resourceURL = nil;
NSString* filePath = nil;
- // first try to find HTTP:// or Documents:// resources
-
+ // The order of checking if url path:
+ // 1. http:// or https://
+ // 2. documents://
+ // 3. cdvfile://
+ // 4. file://
+ // 5. custom app scheme+hostname (e.g. app://localhost/)
+ // 6. starts with a "/"
+ //
+ // For use case 4-6, it will attempt to find file path in "www" or "LocalFileSystem.TEMPORARY" directory
if ([resourcePath hasPrefix:HTTP_SCHEME_PREFIX] || [resourcePath hasPrefix:HTTPS_SCHEME_PREFIX]) {
// if it is a http url, use it
NSLog(@"Will use resource '%@' from the Internet.", resourcePath);
@@ -96,25 +185,15 @@ - (NSURL*)urlForPlaying:(NSString*)resourcePath
if (filePath == nil) {
resourceURL = [NSURL URLWithString:resourcePath];
}
- } else {
- // attempt to find file path in www directory or LocalFileSystem.TEMPORARY directory
- filePath = [self.commandDelegate pathForResource:resourcePath];
- if (filePath == nil) {
- // see if this exists in the documents/temp directory from a previous recording
- NSString* testPath = [NSString stringWithFormat:@"%@/%@", [NSTemporaryDirectory()stringByStandardizingPath], resourcePath];
- if ([[NSFileManager defaultManager] fileExistsAtPath:testPath]) {
- // inefficient as existence will be checked again below but only way to determine if file exists from previous recording
- filePath = testPath;
- NSLog(@"Will attempt to use file resource from LocalFileSystem.TEMPORARY directory");
- } else {
- // attempt to use path provided
- filePath = resourcePath;
- NSLog(@"Will attempt to use file resource '%@'", filePath);
- }
- } else {
- NSLog(@"Found resource '%@' in the web folder.", filePath);
- }
+ } else if ([resourcePath hasPrefix:FILE_PREFIX]) {
+ filePath = [self attemptFindFilePath:resourcePath prefix:FILE_PREFIX];
+ } else if ([self isCdvCustomSchemeUrl:resourcePath]) {
+ NSString *assetUrl = [self getCdvCustomSchemeAssetPrefix];
+ filePath = [self attemptFindFilePath:resourcePath prefix: assetUrl];
+ } else if ([resourcePath hasPrefix:@"/"]) {
+ filePath = [self attemptFindFilePath:resourcePath prefix:@"/"];
}
+
// if the resourcePath resolved to a file path, check that file exists
if (filePath != nil) {
// create resourceURL
@@ -136,7 +215,6 @@ - (CDVAudioFile*)audioFileForResource:(NSString*)resourcePath withId:(NSString*)
BOOL bError = NO;
CDVMediaError errcode = MEDIA_ERR_NONE_SUPPORTED;
NSString* errMsg = @"";
- NSString* jsString = nil;
CDVAudioFile* audioFile = nil;
NSURL* resourceURL = nil;
@@ -174,8 +252,8 @@ - (CDVAudioFile*)audioFileForResource:(NSString*)resourcePath withId:(NSString*)
}
if (bError) {
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:errcode message:errMsg]];
- [self.commandDelegate evalJs:jsString];
+ [self onStatus:MEDIA_ERROR mediaId:mediaId param:
+ [self createMediaErrorWithCode:errcode message:errMsg]];
}
return audioFile;
@@ -207,15 +285,19 @@ - (BOOL)hasAudioSession
}
// helper function to create a error object string
-- (NSString*)createMediaErrorWithCode:(CDVMediaError)code message:(NSString*)message
+- (NSDictionary*)createMediaErrorWithCode:(CDVMediaError)code message:(NSString*)message
{
NSMutableDictionary* errorDict = [NSMutableDictionary dictionaryWithCapacity:2];
[errorDict setObject:[NSNumber numberWithUnsignedInteger:code] forKey:@"code"];
[errorDict setObject:message ? message:@"" forKey:@"message"];
+ return errorDict;
+}
- NSData* jsonData = [NSJSONSerialization dataWithJSONObject:errorDict options:0 error:nil];
- return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
+//helper function to create specifically an abort error
+-(NSDictionary*)createAbortError:(NSString*)message
+{
+ return [self createMediaErrorWithCode:MEDIA_ERR_ABORTED message:message];
}
- (void)create:(CDVInvokedUrlCommand*)command
@@ -227,8 +309,8 @@ - (void)create:(CDVInvokedUrlCommand*)command
if (audioFile == nil) {
NSString* errorMessage = [NSString stringWithFormat:@"Failed to initialize Media file with path %@", resourcePath];
- NSString* jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_ABORTED message:errorMessage]];
- [self.commandDelegate evalJs:jsString];
+ [self onStatus:MEDIA_ERROR mediaId:mediaId param:
+ [self createAbortError:errorMessage]];
} else {
NSURL* resourceUrl = audioFile.resourceURL;
@@ -245,7 +327,11 @@ - (void)create:(CDVInvokedUrlCommand*)command
// Pass the AVPlayerItem to a new player
avPlayer = [[AVPlayer alloc] initWithPlayerItem:playerItem];
- //avPlayer = [[AVPlayer alloc] initWithURL:resourceUrl];
+ // Avoid excessive buffering so streaming media can play instantly on iOS
+ // Removes preplay delay on ios 10+, makes consistent with ios9 behaviour
+ if ([NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){10,0,0}]) {
+ avPlayer.automaticallyWaitsToMinimizeStalling = NO;
+ }
}
self.currMediaId = mediaId;
@@ -270,6 +356,15 @@ - (void)setVolume:(CDVInvokedUrlCommand*)command
if (audioFile.player) {
audioFile.player.volume = [volume floatValue];
}
+ else {
+ float customVolume = [volume floatValue];
+ if (customVolume >= 0.0 && customVolume <= 1.0) {
+ [avPlayer setVolume: customVolume];
+ }
+ else {
+ NSLog(@"The value must be within the range of 0.0 to 1.0");
+ }
+ }
[[self soundCache] setObject:audioFile forKey:mediaId];
}
}
@@ -317,7 +412,6 @@ - (void)startPlayingAudio:(CDVInvokedUrlCommand*)command
NSDictionary* options = [command argumentAtIndex:2 withDefault:nil];
BOOL bError = NO;
- NSString* jsString = nil;
CDVAudioFile* audioFile = [self audioFileForResource:resourcePath withId:mediaId doValidation:YES forRecording:NO];
if ((audioFile != nil) && (audioFile.resourceURL != nil)) {
@@ -353,7 +447,7 @@ - (void)startPlayingAudio:(CDVInvokedUrlCommand*)command
CMTime time = avPlayer.currentItem.asset.duration;
duration = CMTimeGetSeconds(time);
if (isnan(duration)) {
- NSLog(@"Duration is infifnite, setting it to -1");
+ NSLog(@"Duration is infinite, setting it to -1");
duration = -1;
}
@@ -391,8 +485,8 @@ - (void)startPlayingAudio:(CDVInvokedUrlCommand*)command
duration = round(audioFile.player.duration * 1000) / 1000;
}
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%.3f);\n%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_DURATION, duration, @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_RUNNING];
- [self.commandDelegate evalJs:jsString];
+ [self onStatus:MEDIA_DURATION mediaId:mediaId param:@(duration)];
+ [self onStatus:MEDIA_STATE mediaId:mediaId param:@(MEDIA_RUNNING)];
}
}
if (bError) {
@@ -409,9 +503,8 @@ - (void)startPlayingAudio:(CDVInvokedUrlCommand*)command
[audioFile.player play];
} */
// error creating the session or player
- // jsString = [NSString stringWithFormat: @"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, MEDIA_ERR_NONE_SUPPORTED];
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_NONE_SUPPORTED message:nil]];
- [self.commandDelegate evalJs:jsString];
+ [self onStatus:MEDIA_ERROR mediaId:mediaId
+ param:[self createMediaErrorWithCode:MEDIA_ERR_NONE_SUPPORTED message:nil]];
}
}
// else audioFile was nil - error already returned from audioFile for resource
@@ -458,7 +551,7 @@ - (BOOL)prepareToPlay:(CDVAudioFile*)audioFile withId:(NSString*)mediaId
if (playerError != nil) {
NSLog(@"Failed to initialize AVAudioPlayer: %@\n", [playerError localizedDescription]);
audioFile.player = nil;
- if (self.avSession) {
+ if (! keepAvAudioSessionAlwaysActive && self.avSession && ! [self isPlayingOrRecording]) {
[self.avSession setActive:NO error:nil];
}
bError = YES;
@@ -475,13 +568,12 @@ - (void)stopPlayingAudio:(CDVInvokedUrlCommand*)command
{
NSString* mediaId = [command argumentAtIndex:0];
CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId];
- NSString* jsString = nil;
if ((audioFile != nil) && (audioFile.player != nil)) {
NSLog(@"Stopped playing audio sample '%@'", audioFile.resourcePath);
[audioFile.player stop];
audioFile.player.currentTime = 0;
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_STOPPED];
+ [self onStatus:MEDIA_STATE mediaId:mediaId param:@(MEDIA_STOPPED)];
}
// seek to start and pause
if (avPlayer.currentItem && avPlayer.currentItem.asset) {
@@ -493,24 +585,20 @@ - (void)stopPlayingAudio:(CDVInvokedUrlCommand*)command
completionHandler: ^(BOOL finished){
if (finished) [avPlayer pause];
}];
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_STOPPED];
+ [self onStatus:MEDIA_STATE mediaId:mediaId param:@(MEDIA_STOPPED)];
} else {
// cannot seek, wrong state
CDVMediaError errcode = MEDIA_ERR_NONE_ACTIVE;
NSString* errMsg = @"Cannot service stop request until the avPlayer is in 'AVPlayerStatusReadyToPlay' state.";
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:errcode message:errMsg]];
+ [self onStatus:MEDIA_ERROR mediaId:mediaId param:
+ [self createMediaErrorWithCode:errcode message:errMsg]];
}
}
- // ignore if no media playing
- if (jsString) {
- [self.commandDelegate evalJs:jsString];
- }
}
- (void)pausePlayingAudio:(CDVInvokedUrlCommand*)command
{
NSString* mediaId = [command argumentAtIndex:0];
- NSString* jsString = nil;
CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId];
if ((audioFile != nil) && ((audioFile.player != nil) || (avPlayer != nil))) {
@@ -521,12 +609,7 @@ - (void)pausePlayingAudio:(CDVInvokedUrlCommand*)command
[avPlayer pause];
}
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_PAUSED];
- }
- // ignore if no media playing
-
- if (jsString) {
- [self.commandDelegate evalJs:jsString];
+ [self onStatus:MEDIA_STATE mediaId:mediaId param:@(MEDIA_PAUSED)];
}
}
@@ -541,7 +624,6 @@ - (void)seekToAudio:(CDVInvokedUrlCommand*)command
CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId];
double position = [[command argumentAtIndex:1] doubleValue];
double posInSeconds = position / 1000;
- NSString* jsString;
if ((audioFile != nil) && (audioFile.player != nil)) {
@@ -549,12 +631,10 @@ - (void)seekToAudio:(CDVInvokedUrlCommand*)command
// The seek is past the end of file. Stop media and reset to beginning instead of seeking past the end.
[audioFile.player stop];
audioFile.player.currentTime = 0;
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%.3f);\n%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_POSITION, 0.0, @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_STOPPED];
- // NSLog(@"seekToEndJsString=%@",jsString);
+ [self onStatus:MEDIA_STATE mediaId:mediaId param:@(MEDIA_STOPPED)];
} else {
audioFile.player.currentTime = posInSeconds;
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%f);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_POSITION, posInSeconds];
- // NSLog(@"seekJsString=%@",jsString);
+ [self onStatus:MEDIA_POSITION mediaId:mediaId param:@(posInSeconds)];
}
} else if (avPlayer != nil) {
@@ -563,6 +643,7 @@ - (void)seekToAudio:(CDVInvokedUrlCommand*)command
BOOL isPlaying = (avPlayer.rate > 0 && !avPlayer.error);
BOOL isReadyToSeek = (avPlayer.status == AVPlayerStatusReadyToPlay) && (avPlayer.currentItem.status == AVPlayerItemStatusReadyToPlay);
+ float currentPlaybackRate = avPlayer.rate;
// CB-10535:
// When dealing with remote files, we can get into a situation where we start playing before AVPlayer has had the time to buffer the file to be played.
@@ -572,16 +653,18 @@ - (void)seekToAudio:(CDVInvokedUrlCommand*)command
toleranceBefore: kCMTimeZero
toleranceAfter: kCMTimeZero
completionHandler: ^(BOOL finished) {
- if (isPlaying) [avPlayer play];
+ if (isPlaying) {
+ [avPlayer play];
+ // [avPlayer play] sets the rate to 1, so we need to set it again after seeking
+ [avPlayer setRate:currentPlaybackRate];
+ };
}];
} else {
- CDVMediaError errcode = MEDIA_ERR_ABORTED;
NSString* errMsg = @"AVPlayerItem cannot service a seek request with a completion handler until its status is AVPlayerItemStatusReadyToPlay.";
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:errcode message:errMsg]];
+ [self onStatus:MEDIA_ERROR mediaId:mediaId param:
+ [self createAbortError:errMsg]];
}
}
-
- [self.commandDelegate evalJs:jsString];
}
@@ -604,7 +687,8 @@ - (void)release:(CDVInvokedUrlCommand*)command
[avPlayer pause];
avPlayer = nil;
}
- if (self.avSession) {
+ if (! keepAvAudioSessionAlwaysActive && self.avSession && ! [self isPlayingOrRecording]) {
+ [self.avSession setCategory:AVAudioSessionCategorySoloAmbient error:nil];
[self.avSession setActive:NO error:nil];
self.avSession = nil;
}
@@ -631,10 +715,13 @@ - (void)getCurrentPositionAudio:(CDVInvokedUrlCommand*)command
position = CMTimeGetSeconds(time);
}
+ if (isnan(position)){
+ position = -1;
+ }
+
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDouble:position];
- NSString* jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%.3f);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_POSITION, position];
- [self.commandDelegate evalJs:jsString];
+ [self onStatus:MEDIA_POSITION mediaId:mediaId param:@(position)];
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}
@@ -646,7 +733,6 @@ - (void)startRecordingAudio:(CDVInvokedUrlCommand*)command
NSString* mediaId = [command argumentAtIndex:0];
CDVAudioFile* audioFile = [self audioFileForResource:[command argumentAtIndex:1] withId:mediaId doValidation:YES forRecording:YES];
- __block NSString* jsString = nil;
__block NSString* errorMsg = @"";
if ((audioFile != nil) && (audioFile.resourceURL != nil)) {
@@ -669,20 +755,28 @@ - (void)startRecordingAudio:(CDVInvokedUrlCommand*)command
if (![weakSelf.avSession setActive:YES error:&error]) {
// other audio with higher priority that does not allow mixing could cause this to fail
errorMsg = [NSString stringWithFormat:@"Unable to record audio: %@", [error localizedFailureReason]];
- // jsString = [NSString stringWithFormat: @"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, MEDIA_ERR_ABORTED];
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, [weakSelf createMediaErrorWithCode:MEDIA_ERR_ABORTED message:errorMsg]];
- [weakSelf.commandDelegate evalJs:jsString];
+ [weakSelf onStatus:MEDIA_ERROR mediaId:mediaId param:
+ [self createAbortError:errorMsg]];
return;
}
}
// create a new recorder for each start record
- NSDictionary *audioSettings = @{AVFormatIDKey: @(kAudioFormatMPEG4AAC),
- AVSampleRateKey: @(44100),
+ bool isWav=[[audioFile.resourcePath pathExtension] isEqualToString:@"wav"];
+ NSMutableDictionary *audioSettings = [NSMutableDictionary dictionaryWithDictionary:
+ @{AVSampleRateKey: @(44100),
AVNumberOfChannelsKey: @(1),
- AVEncoderAudioQualityKey: @(AVAudioQualityMedium)
- };
- audioFile.recorder = [[CDVAudioRecorder alloc] initWithURL:audioFile.resourceURL settings:nil error:&error];
+ }];
+ if (isWav) {
+ audioSettings[AVFormatIDKey]=@(kAudioFormatLinearPCM);
+ audioSettings[AVLinearPCMBitDepthKey]=@(16);
+ audioSettings[AVLinearPCMIsBigEndianKey]=@(false);
+ audioSettings[AVLinearPCMIsFloatKey]=@(false);
+ } else {
+ audioSettings[AVFormatIDKey]=@(kAudioFormatMPEG4AAC);
+ audioSettings[AVEncoderAudioQualityKey]=@(AVAudioQualityMedium);
+ }
+ audioFile.recorder = [[CDVAudioRecorder alloc] initWithURL:audioFile.resourceURL settings:audioSettings error:&error];
bool recordingSuccess = NO;
if (error == nil) {
@@ -692,8 +786,7 @@ - (void)startRecordingAudio:(CDVInvokedUrlCommand*)command
recordingSuccess = [audioFile.recorder record];
if (recordingSuccess) {
NSLog(@"Started recording audio sample '%@'", audioFile.resourcePath);
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_RUNNING];
- [weakSelf.commandDelegate evalJs:jsString];
+ [weakSelf onStatus:MEDIA_STATE mediaId:mediaId param:@(MEDIA_RUNNING)];
}
}
@@ -704,11 +797,11 @@ - (void)startRecordingAudio:(CDVInvokedUrlCommand*)command
errorMsg = @"Failed to start recording using AVAudioRecorder";
}
audioFile.recorder = nil;
- if (weakSelf.avSession) {
+ if (! keepAvAudioSessionAlwaysActive && weakSelf.avSession && ! [self isPlayingOrRecording]) {
[weakSelf.avSession setActive:NO error:nil];
}
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, [weakSelf createMediaErrorWithCode:MEDIA_ERR_ABORTED message:errorMsg]];
- [weakSelf.commandDelegate evalJs:jsString];
+ [weakSelf onStatus:MEDIA_ERROR mediaId:mediaId param:
+ [self createAbortError:errorMsg]];
}
};
@@ -724,11 +817,11 @@ - (void)startRecordingAudio:(CDVInvokedUrlCommand*)command
NSString* msg = @"Error creating audio session, microphone permission denied.";
NSLog(@"%@", msg);
audioFile.recorder = nil;
- if (weakSelf.avSession) {
+ if (! keepAvAudioSessionAlwaysActive && weakSelf.avSession && ! [self isPlayingOrRecording]) {
[weakSelf.avSession setActive:NO error:nil];
}
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_ABORTED message:msg]];
- [weakSelf.commandDelegate evalJs:jsString];
+ [weakSelf onStatus:MEDIA_ERROR mediaId:mediaId param:
+ [self createAbortError:msg]];
}
}];
#pragma clang diagnostic pop
@@ -739,8 +832,8 @@ - (void)startRecordingAudio:(CDVInvokedUrlCommand*)command
} else {
// file did not validate
NSString* errorMsg = [NSString stringWithFormat:@"Could not record audio at '%@'", audioFile.resourcePath];
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_ABORTED message:errorMsg]];
- [self.commandDelegate evalJs:jsString];
+ [self onStatus:MEDIA_ERROR mediaId:mediaId param:
+ [self createAbortError:errorMsg]];
}
}
@@ -749,17 +842,12 @@ - (void)stopRecordingAudio:(CDVInvokedUrlCommand*)command
NSString* mediaId = [command argumentAtIndex:0];
CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId];
- NSString* jsString = nil;
if ((audioFile != nil) && (audioFile.recorder != nil)) {
NSLog(@"Stopped recording audio sample '%@'", audioFile.resourcePath);
[audioFile.recorder stop];
// no callback - that will happen in audioRecorderDidFinishRecording
}
- // ignore if no media recording
- if (jsString) {
- [self.commandDelegate evalJs:jsString];
- }
}
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder*)recorder successfully:(BOOL)flag
@@ -767,21 +855,19 @@ - (void)audioRecorderDidFinishRecording:(AVAudioRecorder*)recorder successfully:
CDVAudioRecorder* aRecorder = (CDVAudioRecorder*)recorder;
NSString* mediaId = aRecorder.mediaId;
CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId];
- NSString* jsString = nil;
if (audioFile != nil) {
NSLog(@"Finished recording audio sample '%@'", audioFile.resourcePath);
}
if (flag) {
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_STOPPED];
+ [self onStatus:MEDIA_STATE mediaId:mediaId param:@(MEDIA_STOPPED)];
} else {
- // jsString = [NSString stringWithFormat: @"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, MEDIA_ERR_DECODE];
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_DECODE message:nil]];
+ [self onStatus:MEDIA_ERROR mediaId:mediaId param:
+ [self createMediaErrorWithCode:MEDIA_ERR_DECODE message:nil]];
}
- if (self.avSession) {
+ if (! keepAvAudioSessionAlwaysActive && self.avSession && ! [self isPlayingOrRecording]) {
[self.avSession setActive:NO error:nil];
}
- [self.commandDelegate evalJs:jsString];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer*)player successfully:(BOOL)flag
@@ -790,50 +876,68 @@ - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer*)player successfully:(BOOL)fl
CDVAudioPlayer* aPlayer = (CDVAudioPlayer*)player;
NSString* mediaId = aPlayer.mediaId;
CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId];
- NSString* jsString = nil;
if (audioFile != nil) {
NSLog(@"Finished playing audio sample '%@'", audioFile.resourcePath);
}
if (flag) {
audioFile.player.currentTime = 0;
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_STOPPED];
+ [self onStatus:MEDIA_STATE mediaId:mediaId param:@(MEDIA_STOPPED)];
} else {
- // jsString = [NSString stringWithFormat: @"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, MEDIA_ERR_DECODE];
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_DECODE message:nil]];
+ [self onStatus:MEDIA_ERROR mediaId:mediaId param:
+ [self createMediaErrorWithCode:MEDIA_ERR_DECODE message:nil]];
}
- if (self.avSession) {
- [self.avSession setActive:NO error:nil];
- }
- [self.commandDelegate evalJs:jsString];
+ if (! keepAvAudioSessionAlwaysActive && self.avSession && ! [self isPlayingOrRecording]) {
+ [self.avSession setActive:NO error:nil];
+ }
}
-(void)itemDidFinishPlaying:(NSNotification *) notification {
// Will be called when AVPlayer finishes playing playerItem
NSString* mediaId = self.currMediaId;
- NSString* jsString = nil;
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_STOPPED];
- if (self.avSession) {
- [self.avSession setActive:NO error:nil];
- }
- [self.commandDelegate evalJs:jsString];
+ if (! keepAvAudioSessionAlwaysActive && self.avSession && ! [self isPlayingOrRecording]) {
+ [self.avSession setActive:NO error:nil];
+ }
+ [self onStatus:MEDIA_STATE mediaId:mediaId param:@(MEDIA_STOPPED)];
}
-(void)itemStalledPlaying:(NSNotification *) notification {
// Will be called when playback stalls due to buffer empty
NSLog(@"Stalled playback");
+ NSString* errMsg = @"stalled_playback";
+ NSString* mediaId = self.currMediaId;
+ [self onStatus:MEDIA_ERROR mediaId:mediaId param:
+ [self createAbortError:errMsg]];
}
- (void)onMemoryWarning
{
- [[self soundCache] removeAllObjects];
- [self setSoundCache:nil];
+ /* https://issues.apache.org/jira/browse/CB-11513 */
+ NSMutableArray* keysToRemove = [[NSMutableArray alloc] init];
+
+ for(id key in [self soundCache]) {
+ CDVAudioFile* audioFile = [[self soundCache] objectForKey:key];
+ if (audioFile != nil) {
+ if (audioFile.player != nil && ![audioFile.player isPlaying]) {
+ [keysToRemove addObject:key];
+ }
+ if (audioFile.recorder != nil && ![audioFile.recorder isRecording]) {
+ [keysToRemove addObject:key];
+ }
+ }
+ }
+
+ [[self soundCache] removeObjectsForKeys:keysToRemove];
+
+ // [[self soundCache] removeAllObjects];
+ // [self setSoundCache:nil];
[self setAvSession:nil];
[super onMemoryWarning];
}
+
- (void)dealloc
{
[[self soundCache] removeAllObjects];
@@ -891,19 +995,14 @@ - (void)resumeRecordingAudio:(CDVInvokedUrlCommand*)command
NSString* mediaId = [command argumentAtIndex:0];
CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId];
- NSString* jsString = nil;
if ((audioFile != nil) && (audioFile.recorder != nil)) {
NSLog(@"Resumed recording audio sample '%@'", audioFile.resourcePath);
[audioFile.recorder record];
// no callback - that will happen in audioRecorderDidFinishRecording
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_RUNNING];
+ [self onStatus:MEDIA_STATE mediaId:mediaId param:@(MEDIA_RUNNING)];
}
- // ignore if no media recording
- if (jsString) {
- [self.commandDelegate evalJs:jsString];
- }
}
- (void)pauseRecordingAudio:(CDVInvokedUrlCommand*)command
@@ -911,22 +1010,61 @@ - (void)pauseRecordingAudio:(CDVInvokedUrlCommand*)command
NSString* mediaId = [command argumentAtIndex:0];
CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId];
- NSString* jsString = nil;
if ((audioFile != nil) && (audioFile.recorder != nil)) {
NSLog(@"Paused recording audio sample '%@'", audioFile.resourcePath);
[audioFile.recorder pause];
// no callback - that will happen in audioRecorderDidFinishRecording
- // no callback - that will happen in audioRecorderDidFinishRecording
- jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('cordova-plugin-media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_PAUSED];
+ [self onStatus:MEDIA_STATE mediaId:mediaId param:@(MEDIA_PAUSED)];
}
-
- // ignore if no media recording
- if (jsString) {
- [self.commandDelegate evalJs:jsString];
- }
}
+- (void)messageChannel:(CDVInvokedUrlCommand*)command
+{
+ self.statusCallbackId = command.callbackId;
+}
+
+- (void)onStatus:(CDVMediaMsg)what mediaId:(NSString*)mediaId param:(NSObject*)param
+{
+ if (self.statusCallbackId!=nil) { //new way, android compatible
+ NSMutableDictionary* status=[NSMutableDictionary dictionary];
+ status[@"msgType"] = @(what);
+ //in the error case contains a dict with "code" and "message"
+ //otherwise a NSNumber
+ status[@"value"] = param;
+ status[@"id"] = mediaId;
+ NSMutableDictionary* dict=[NSMutableDictionary dictionary];
+ dict[@"action"] = @"status";
+ dict[@"status"] = status;
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dict];
+ [result setKeepCallbackAsBool:YES]; //we keep this forever
+ [self.commandDelegate sendPluginResult:result callbackId:self.statusCallbackId];
+ } else { //old school evalJs way
+ if (what==MEDIA_ERROR) {
+ NSData* jsonData = [NSJSONSerialization dataWithJSONObject:param options:0 error:nil];
+ param=[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
+ }
+ NSString* jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);",
+ @"cordova.require('cordova-plugin-media.Media').onStatus",
+ mediaId, (int)what, param];
+ [self.commandDelegate evalJs:jsString];
+ }
+}
+
+-(BOOL) isPlayingOrRecording
+{
+ for(NSString* mediaId in soundCache) {
+ CDVAudioFile* audioFile = [soundCache objectForKey:mediaId];
+ if (audioFile.player && [audioFile.player isPlaying]) {
+ return true;
+ }
+ if (audioFile.recorder && [audioFile.recorder isRecording]) {
+ return true;
+ }
+ }
+ return false;
+}
+
@end
@implementation CDVAudioFile
diff --git a/src/tizen/MediaProxy.js b/src/tizen/MediaProxy.js
deleted file mode 100644
index 15ab7f012..000000000
--- a/src/tizen/MediaProxy.js
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/* global webkitURL */
-
-var Media = require('cordova-plugin-media.Media');
-
-var MediaError = require('cordova-plugin-media.MediaError'),
- audioObjects = {};
-
-module.exports = {
- // Initiates the audio file
- create:function(successCallback, errorCallback, args) {
- var id = args[0], src = args[1];
-
- console.log("media::create() - id =" + id + ", src =" + src);
-
- audioObjects[id] = new Audio(src);
-
- audioObjects[id].onStalledCB = function () {
- console.log("media::onStalled()");
-
- audioObjects[id].timer = window.setTimeout(
- function () {
- audioObjects[id].pause();
-
- if (audioObjects[id].currentTime !== 0)
- audioObjects[id].currentTime = 0;
-
- console.log("media::onStalled() - MEDIA_ERROR -> " + MediaError.MEDIA_ERR_ABORTED);
-
- var err = new MediaError(MediaError.MEDIA_ERR_ABORTED, "Stalled");
-
- Media.onStatus(id, Media.MEDIA_ERROR, err);
- },
- 2000);
- };
-
- audioObjects[id].onEndedCB = function () {
- console.log("media::onEndedCB() - MEDIA_STATE -> MEDIA_STOPPED");
-
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
- };
-
- audioObjects[id].onErrorCB = function () {
- console.log("media::onErrorCB() - MEDIA_ERROR -> " + event.srcElement.error);
-
- Media.onStatus(id, Media.MEDIA_ERROR, event.srcElement.error);
- };
-
- audioObjects[id].onPlayCB = function () {
- console.log("media::onPlayCB() - MEDIA_STATE -> MEDIA_STARTING");
-
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING);
- };
-
- audioObjects[id].onPlayingCB = function () {
- console.log("media::onPlayingCB() - MEDIA_STATE -> MEDIA_RUNNING");
-
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING);
- };
-
- audioObjects[id].onDurationChangeCB = function () {
- console.log("media::onDurationChangeCB() - MEDIA_DURATION -> " + audioObjects[id].duration);
-
- Media.onStatus(id, Media.MEDIA_DURATION, audioObjects[id].duration);
- };
-
- audioObjects[id].onTimeUpdateCB = function () {
- console.log("media::onTimeUpdateCB() - MEDIA_POSITION -> " + audioObjects[id].currentTime);
-
- Media.onStatus(id, Media.MEDIA_POSITION, audioObjects[id].currentTime);
- };
-
- audioObjects[id].onCanPlayCB = function () {
- console.log("media::onCanPlayCB()");
-
- window.clearTimeout(audioObjects[id].timer);
-
- audioObjects[id].play();
- };
-
- },
-
- // Start playing the audio
- startPlayingAudio:function(successCallback, errorCallback, args) {
- var id = args[0], src = args[1], options = args[2];
-
- console.log("media::startPlayingAudio() - id =" + id + ", src =" + src + ", options =" + options);
-
- audioObjects[id].addEventListener('canplay', audioObjects[id].onCanPlayCB);
- audioObjects[id].addEventListener('ended', audioObjects[id].onEndedCB);
- audioObjects[id].addEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);
- audioObjects[id].addEventListener('durationchange', audioObjects[id].onDurationChangeCB);
- audioObjects[id].addEventListener('playing', audioObjects[id].onPlayingCB);
- audioObjects[id].addEventListener('play', audioObjects[id].onPlayCB);
- audioObjects[id].addEventListener('error', audioObjects[id].onErrorCB);
- audioObjects[id].addEventListener('stalled', audioObjects[id].onStalledCB);
-
- audioObjects[id].play();
- },
-
- // Stops the playing audio
- stopPlayingAudio:function(successCallback, errorCallback, args) {
- var id = args[0];
-
- window.clearTimeout(audioObjects[id].timer);
-
- audioObjects[id].pause();
-
- if (audioObjects[id].currentTime !== 0)
- audioObjects[id].currentTime = 0;
-
- console.log("media::stopPlayingAudio() - MEDIA_STATE -> MEDIA_STOPPED");
-
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
-
- audioObjects[id].removeEventListener('canplay', audioObjects[id].onCanPlayCB);
- audioObjects[id].removeEventListener('ended', audioObjects[id].onEndedCB);
- audioObjects[id].removeEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);
- audioObjects[id].removeEventListener('durationchange', audioObjects[id].onDurationChangeCB);
- audioObjects[id].removeEventListener('playing', audioObjects[id].onPlayingCB);
- audioObjects[id].removeEventListener('play', audioObjects[id].onPlayCB);
- audioObjects[id].removeEventListener('error', audioObjects[id].onErrorCB);
- audioObjects[id].removeEventListener('error', audioObjects[id].onStalledCB);
- },
-
- // Seeks to the position in the audio
- seekToAudio:function(successCallback, errorCallback, args) {
- var id = args[0], milliseconds = args[1];
-
- console.log("media::seekToAudio()");
-
- audioObjects[id].currentTime = milliseconds;
- successCallback( audioObjects[id].currentTime);
- },
-
- // Pauses the playing audio
- pausePlayingAudio:function(successCallback, errorCallback, args) {
- var id = args[0];
-
- console.log("media::pausePlayingAudio() - MEDIA_STATE -> MEDIA_PAUSED");
-
- audioObjects[id].pause();
-
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED);
- },
-
- // Gets current position in the audio
- getCurrentPositionAudio:function(successCallback, errorCallback, args) {
- var id = args[0];
- console.log("media::getCurrentPositionAudio()");
- successCallback(audioObjects[id].currentTime);
- },
-
- // Start recording audio
- startRecordingAudio:function(successCallback, errorCallback, args) {
- var id = args[0], src = args[1];
-
- console.log("media::startRecordingAudio() - id =" + id + ", src =" + src);
-
- function gotStreamCB(stream) {
- audioObjects[id].src = webkitURL.createObjectURL(stream);
- console.log("media::startRecordingAudio() - stream CB");
- }
-
- function gotStreamFailedCB(error) {
- console.log("media::startRecordingAudio() - error CB:" + error.toString());
- }
-
- if (navigator.webkitGetUserMedia) {
- audioObjects[id] = new Audio();
- navigator.webkitGetUserMedia('audio', gotStreamCB, gotStreamFailedCB);
- } else {
- console.log("webkitGetUserMedia not supported");
- }
- successCallback();
- },
-
- // Stop recording audio
- stopRecordingAudio:function(successCallback, errorCallback, args) {
- var id = args[0];
-
- console.log("media::stopRecordingAudio() - id =" + id);
-
- audioObjects[id].pause();
- successCallback();
- },
-
- // Release the media object
- release:function(successCallback, errorCallback, args) {
- var id = args[0];
- window.clearTimeout(audioObjects[id].timer);
- console.log("media::release()");
- },
-
- setVolume:function(successCallback, errorCallback, args) {
- var id = args[0], volume = args[1];
-
- console.log("media::setVolume()");
-
- audioObjects[id].volume = volume;
- }
-};
-
-require("cordova/tizen/commandProxy").add("Media", module.exports);
diff --git a/src/ubuntu/media.cpp b/src/ubuntu/media.cpp
deleted file mode 100644
index 2814b5b33..000000000
--- a/src/ubuntu/media.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-#include "media.h"
-
-void Media::create(int scId, int ecId, const QString &id, const QString &src) {
- Q_UNUSED(scId);
- Q_UNUSED(ecId);
-
- if (_id2Player.find(id) != _id2Player.end()) {
- _id2Player[id]->stop();
- _id2Player.remove(id);
- }
-
- _id2Player[id] = QSharedPointer(new Player(id, src, this));
-}
-
-void Media::relase(int scId, int ecId, const QString &id) {
- Q_UNUSED(scId);
- Q_UNUSED(ecId);
-
- if (_id2Player.find(id) == _id2Player.end())
- return;
- _id2Player.remove(id);
-}
-
-void Media::startPlayingAudio(int scId, int ecId, const QString &id, const QString &src, QVariantMap options) {
- Q_UNUSED(scId);
- Q_UNUSED(ecId);
- Q_UNUSED(src);
- Q_UNUSED(options);
-
- if (_id2Player.find(id) == _id2Player.end())
- return;
- QSharedPointer player = _id2Player[id];
- player->play();
-}
-
-void Media::pausePlayingAudio(int scId, int ecId, const QString &id) {
- Q_UNUSED(scId);
- Q_UNUSED(ecId);
-
- if (_id2Player.find(id) == _id2Player.end())
- return;
- QSharedPointer player = _id2Player[id];
- player->pause();
-}
-
-void Media::stopPlayingAudio(int scId, int ecId, const QString &id) {
- Q_UNUSED(scId);
- Q_UNUSED(ecId);
-
- if (_id2Player.find(id) == _id2Player.end())
- return;
- QSharedPointer player = _id2Player[id];
- player->stop();
-}
-
-void Media::startRecordingAudio(int scId, int ecId, const QString &id, const QString &src) {
- Q_UNUSED(scId);
- Q_UNUSED(ecId);
- Q_UNUSED(src);
-
- if (_id2Player.find(id) == _id2Player.end())
- return;
- QSharedPointer player = _id2Player[id];
- player->startRecording();
-}
-
-void Media::stopRecordingAudio(int scId, int ecId, const QString &id) {
- Q_UNUSED(scId);
- Q_UNUSED(ecId);
-
- if (_id2Player.find(id) == _id2Player.end())
- return;
- QSharedPointer player = _id2Player[id];
- player->stopRecording();
-}
-
-void Media::getCurrentPositionAudio(int scId, int ecId, const QString &id) {
- Q_UNUSED(ecId);
-
- if (_id2Player.find(id) == _id2Player.end())
- return;
-
- QSharedPointer player = _id2Player[id];
- double position = player->getPosition();
- this->cb(scId, position);
-}
-
-void Media::seekToAudio(int scId, int ecId, const QString &id, qint64 position) {
- Q_UNUSED(scId);
- Q_UNUSED(ecId);
-
- if (_id2Player.find(id) == _id2Player.end())
- return;
-
- QSharedPointer player = _id2Player[id];
- player->seekTo(position);
-}
-
-void Media::setVolume(int scId, int ecId, const QString &id, int volume) {
- Q_UNUSED(scId);
- Q_UNUSED(ecId);
-
- if (_id2Player.find(id) == _id2Player.end())
- return;
- QSharedPointer player = _id2Player[id];
- player->setVolume(volume);
-}
diff --git a/src/ubuntu/media.h b/src/ubuntu/media.h
deleted file mode 100644
index c1f371228..000000000
--- a/src/ubuntu/media.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-#ifndef MEDIA_H_789768978
-#define MEDIA_H_789768978
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-class Player;
-
-class Media: public CPlugin {
- Q_OBJECT
-public:
- explicit Media(Cordova *cordova): CPlugin(cordova) {
- }
-
- virtual const QString fullName() override {
- return Media::fullID();
- }
-
- virtual const QString shortName() override {
- return "Media";
- }
-
- static const QString fullID() {
- return "Media";
- }
-
- enum State {
- MEDIA_NONE = 0,
- MEDIA_STARTING = 1,
- MEDIA_RUNNING = 2,
- MEDIA_PAUSED = 3,
- MEDIA_STOPPED = 4
- };
- enum ErrorCode {
- MEDIA_ERR_NONE_ACTIVE = 0,
- MEDIA_ERR_ABORTED = 1,
- MEDIA_ERR_NETWORK = 2,
- MEDIA_ERR_DECODE = 3,
- MEDIA_ERR_NONE_SUPPORTED = 4
- };
-
- void execJS(const QString &js) {
- m_cordova->execJS(js);
- }
-public slots:
- void create(int scId, int ecId, const QString &id, const QString &src);
- void relase(int scId, int ecId, const QString &id);
-
- void startRecordingAudio(int scId, int ecId, const QString &id, const QString &src);
- void stopRecordingAudio(int scId, int ecId, const QString &id);
-
- void startPlayingAudio(int scId, int ecId, const QString &id, const QString &src, QVariantMap options);
- void pausePlayingAudio(int scId, int ecId, const QString &id);
- void stopPlayingAudio(int scId, int ecId, const QString &id);
- void getCurrentPositionAudio(int scId, int ecId, const QString &id);
- void seekToAudio(int scId, int ecId, const QString &id, qint64 position);
- void setVolume(int scId, int ecId, const QString &id, int volume);
-
-private:
- QMap > _id2Player;
-};
-
-class Player: public QObject {
- Q_OBJECT
-public:
- Player(const QString &id, QString src, Media *plugin):
- _state(Media::MEDIA_NONE),
- _src(src),
- _mode(MODE_NONE),
- _plugin(plugin),
- _id(id),
- _stateChanged(false) {
- QUrl url(src, QUrl::TolerantMode);
-
- if (url.scheme().isEmpty()) {
- QAudioEncoderSettings audioSettings;
-
- _recorder.setEncodingSettings(audioSettings);
- _recorder.setOutputLocation(QFileInfo(src).absoluteFilePath());
-
- _player.setMedia(QUrl::fromLocalFile(QFileInfo(src).absoluteFilePath()));
- } else {
- _player.setMedia(url);
- }
- QObject::connect(&_player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(onMediaStatusChanged(QMediaPlayer::MediaStatus)));
- QObject::connect(&_recorder, SIGNAL(error(QMediaRecorder::Error)), this, SLOT(onError(QMediaRecorder::Error)));
-
- connect(&_timer, SIGNAL(timeout()), this, SLOT(reportPosition()));
- }
-
- void startRecording() {
- if (recordMode() && _state != Media::MEDIA_RUNNING) {
- _recorder.record();
- setState(Media::MEDIA_RUNNING);
- }
- }
- void stopRecording() {
- if (recordMode() && _state == Media::MEDIA_RUNNING) {
- _recorder.stop();
- setState(Media::MEDIA_STOPPED);
- }
- }
-
- void setVolume(int volume) {
- _player.setVolume(volume);
- }
-
- void play() {
- if (playMode() && _state != Media::MEDIA_RUNNING) {
- _player.play();
- setState(Media::MEDIA_RUNNING);
- }
- }
- void pause() {
- if (playMode() && _state == Media::MEDIA_RUNNING) {
- _player.pause();
- setState(Media::MEDIA_PAUSED);
- }
- }
- void stop() {
- if (playMode() && (_state == Media::MEDIA_RUNNING || _state == Media::MEDIA_PAUSED)) {
- _player.stop();
- setState(Media::MEDIA_STOPPED);
- }
- }
- double getDuration() {
- if (_mode == MODE_NONE || _player.duration() == -1)
- return -1;
- if (_mode != MODE_PLAY)
- return -2;
- return static_cast(_player.duration()) / 1000.0;
- }
- double getPosition() {
- if (_mode != MODE_PLAY)
- return -1;
- return static_cast(_player.position()) / 1000.0;
- }
- bool seekTo(qint64 position) {
- if (!_player.isSeekable())
- return false;
- _player.setPosition(position * 1000);
- return true;
- }
-private slots:
- void reportPosition() {
- double position = getPosition();
- _plugin->execJS(QString("Media.onStatus('%1', Media.MEDIA_POSITION, %2)")
- .arg(_id).arg(position));
- double duration = getDuration();
- _plugin->execJS(QString("Media.onStatus('%1', Media.MEDIA_DURATION, %2)")
- .arg(_id).arg(duration));
-
- if (_stateChanged && !(_state == Media::MEDIA_RUNNING && (duration == -1 || position == 0))) {
- qCritical() << _id << "POSITION" << position << ":" << duration;
- _stateChanged = false;
- _plugin->execJS(QString("Media.onStatus('%1', Media.MEDIA_STATE, %2)").arg(_id).arg(_state));
- }
- }
-
- void onMediaStatusChanged(QMediaPlayer::MediaStatus status) {
- if (status == QMediaPlayer::InvalidMedia) {
- reportError(Media::MEDIA_ERR_ABORTED, "AudioPlayer Error: The current media cannot be played.");
- setState(Media::MEDIA_STOPPED);
- }
- if (status == QMediaPlayer::EndOfMedia) {
- setState(Media::MEDIA_STOPPED);
- seekTo(0);
- }
- }
- void onError(QMediaRecorder::Error) {
- reportError(Media::MEDIA_ERR_NONE_SUPPORTED, "AudioPlayer Error: Device is not ready or not available.");
- setState(Media::MEDIA_STOPPED);
- }
-
-private:
- void reportError(int code, const QString &descr) {
- Q_UNUSED(descr);
- _plugin->execJS(QString("Media.onStatus('%1', Media.MEDIA_ERROR, {code: %2})")
- .arg(_id).arg(code));
- }
-
- bool playMode() {
- switch (_mode) {
- case Player::MODE_NONE:
- _mode = MODE_PLAY;
- break;
- case Player::MODE_PLAY:
- break;
- case Player::MODE_RECORD:
- reportError(Media::MEDIA_ERR_NONE_SUPPORTED, "AudioPlayer Error: Can't play in record mode.");
- return false;
- break;
- }
- return true;
- }
-
- bool recordMode() {
- switch (_mode) {
- case Player::MODE_NONE:
- if (_recorder.outputLocation().isEmpty()) {
- reportError(Media::MEDIA_ERR_NONE_SUPPORTED, "AudioPlayer Error: unsupported output location.");
- return false;
- }
- _mode = MODE_RECORD;
- break;
- case Player::MODE_PLAY:
- reportError(Media::MEDIA_ERR_NONE_SUPPORTED, "AudioPlayer Error: Can't play in play mode.");
- return false;
- break;
- case Player::MODE_RECORD:
- break;
- }
- return true;
- }
-
- void setState(Media::State state) {
- _state = state;
- _stateChanged = true;
- _timer.start(250);
- }
-
- QMediaPlayer _player;
-
- QAudioRecorder _recorder;
- QTimer _timer;
-
- Media::State _state;
- QString _src;
- enum Mode {
- MODE_NONE,
- MODE_PLAY,
- MODE_RECORD
- };
- Mode _mode;
- Media *_plugin;
- QString _id;
-
- bool _stateChanged;
-};
-
-#endif
diff --git a/src/windows/MediaProxy.js b/src/windows/MediaProxy.js
deleted file mode 100644
index d7fe29404..000000000
--- a/src/windows/MediaProxy.js
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*global Windows:true */
-
-var Media = require('cordova-plugin-media.Media');
-var MediaError = require('cordova-plugin-media.MediaError');
-
-var recordedFile;
-var tempFolderAppDataBasePath = 'ms-appdata:///temp/',
- localFolderAppDataBasePath = 'ms-appdata:///local/',
- tempFolderFullPath = Windows.Storage.ApplicationData.current.temporaryFolder.path,
- localFolderFullPath = Windows.Storage.ApplicationData.current.localFolder.path;
-
-var PARAMETER_IS_INCORRECT = -2147024809;
-var SUPPORTED_EXTENSIONS = ['.mp3', '.wma', '.wav', '.cda', '.adx', '.wm', '.m3u', '.wmx', '.m4a'];
-var SUPPORTED_PREFIXES = ['http', 'https', 'rstp'];
-
-var fsTypes = {
- PERSISTENT: 'PERSISTENT',
- TEMPORARY: 'TEMPORARY'
-};
-
-module.exports = {
- mediaCaptureMrg:null,
-
- // Initiates the audio file
- create:function(win, lose, args) {
- var id = args[0];
-
- var srcUri = processUri(args[1]);
-
- var createAudioNode = !!args[2];
- var thisM = Media.get(id);
-
- Media.prototype.node = null;
-
- var prefix = args[1].split(':').shift();
- var extension = srcUri.extension;
- if (thisM.node === null) {
- if (SUPPORTED_EXTENSIONS.indexOf(extension) === -1 && SUPPORTED_PREFIXES.indexOf(prefix) === -1) {
- if (lose) {
- lose({ code: MediaError.MEDIA_ERR_ABORTED });
- }
- return false; // unable to create
- }
-
- // Don't create Audio object in case of record mode
- if (createAudioNode === true) {
- thisM.node = new Audio();
- thisM.node.msAudioCategory = "BackgroundCapableMedia";
- thisM.node.src = srcUri.absoluteCanonicalUri;
-
- thisM.node.onloadstart = function () {
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING);
- };
-
- thisM.node.ontimeupdate = function (e) {
- Media.onStatus(id, Media.MEDIA_POSITION, e.target.currentTime);
- };
-
- thisM.node.onplaying = function () {
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING);
- };
-
- thisM.node.ondurationchange = function (e) {
- Media.onStatus(id, Media.MEDIA_DURATION, e.target.duration || -1);
- };
-
- thisM.node.onerror = function (e) {
- // Due to media.spec.15 It should return MediaError for bad filename
- var err = e.target.error.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED ?
- { code: MediaError.MEDIA_ERR_ABORTED } :
- e.target.error;
-
- Media.onStatus(id, Media.MEDIA_ERROR, err);
- };
-
- thisM.node.onended = function () {
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
- };
- }
- }
-
- return true; // successfully created
- },
-
- // Start playing the audio
- startPlayingAudio:function(win, lose, args) {
- var id = args[0];
- //var src = args[1];
- //var options = args[2];
-
- var thisM = Media.get(id);
- // if Media was released, then node will be null and we need to create it again
- if (!thisM.node) {
- args[2] = true; // Setting createAudioNode to true
- if (!module.exports.create(win, lose, args)) {
- // there is no reason to continue if we can't create media
- // corresponding callback has been invoked in create so we don't need to call it here
- return;
- }
- }
-
- try {
- thisM.node.play();
- } catch (err) {
- if (lose) {
- lose({code:MediaError.MEDIA_ERR_ABORTED});
- }
- }
- },
-
- // Stops the playing audio
- stopPlayingAudio:function(win, lose, args) {
- var id = args[0];
- try {
- var thisM = Media.get(id);
- thisM.node.pause();
- thisM.node.currentTime = 0;
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
- } catch (err) {
- lose("Failed to stop: "+err);
- }
- },
-
- // Seeks to the position in the audio
- seekToAudio:function(win, lose, args) {
- var id = args[0];
- var milliseconds = args[1];
- var thisM = Media.get(id);
- try {
- thisM.node.currentTime = milliseconds / 1000;
- win(thisM.node.currentTime);
- } catch (err) {
- lose("Failed to seek: "+err);
- }
- },
-
- // Pauses the playing audio
- pausePlayingAudio:function(win, lose, args) {
- var id = args[0];
- var thisM = Media.get(id);
- try {
- thisM.node.pause();
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED);
- } catch (err) {
- lose("Failed to pause: "+err);
- }
- },
-
- // Gets current position in the audio
- getCurrentPositionAudio:function(win, lose, args) {
- var id = args[0];
- try {
- var p = (Media.get(id)).node.currentTime;
- win(p);
- } catch (err) {
- lose(err);
- }
- },
-
- // Start recording audio
- startRecordingAudio:function(win, lose, args) {
- var id = args[0];
- var srcUri = processUri(args[1]);
-
- var dest = parseUriToPathAndFilename(srcUri);
- var destFileName = dest.fileName;
-
- var success = function () {
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING);
- };
-
- var error = function (reason) {
- Media.onStatus(id, Media.MEDIA_ERROR, reason);
- };
-
- // Initialize device
- Media.prototype.mediaCaptureMgr = null;
- var thisM = (Media.get(id));
- var captureInitSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings();
- captureInitSettings.streamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.audio;
- thisM.mediaCaptureMgr = new Windows.Media.Capture.MediaCapture();
- thisM.mediaCaptureMgr.addEventListener("failed", error);
-
- thisM.mediaCaptureMgr.initializeAsync(captureInitSettings).done(function (result) {
- thisM.mediaCaptureMgr.addEventListener("recordlimitationexceeded", error);
- thisM.mediaCaptureMgr.addEventListener("failed", error);
-
- // Start recording
- Windows.Storage.ApplicationData.current.temporaryFolder.createFileAsync(destFileName, Windows.Storage.CreationCollisionOption.replaceExisting).done(function (newFile) {
- recordedFile = newFile;
- var encodingProfile = null;
- switch (newFile.fileType) {
- case '.m4a':
- encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createM4a(Windows.Media.MediaProperties.AudioEncodingQuality.auto);
- break;
- case '.mp3':
- encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createMp3(Windows.Media.MediaProperties.AudioEncodingQuality.auto);
- break;
- case '.wma':
- encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createWma(Windows.Media.MediaProperties.AudioEncodingQuality.auto);
- break;
- default:
- error("Invalid file type for record");
- break;
- }
- thisM.mediaCaptureMgr.startRecordToStorageFileAsync(encodingProfile, newFile).done(success, error);
- }, error);
- }, error);
- },
-
- // Stop recording audio
- stopRecordingAudio:function(win, lose, args) {
- var id = args[0];
- var thisM = Media.get(id);
- var srcUri = processUri(thisM.src);
-
- var dest = parseUriToPathAndFilename(srcUri);
- var destPath = dest.path;
- var destFileName = dest.fileName;
- var fsType = dest.fsType;
-
- var success = function () {
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
- };
-
- var error = function (reason) {
- Media.onStatus(id, Media.MEDIA_ERROR, reason);
- };
-
- thisM.mediaCaptureMgr.stopRecordAsync().done(function () {
- if (fsType === fsTypes.TEMPORARY) {
- if (!destPath) {
- // if path is not defined, we leave recorded file in temporary folder (similar to iOS)
- success();
- } else {
- Windows.Storage.ApplicationData.current.temporaryFolder.getFolderAsync(destPath).done(function (destFolder) {
- recordedFile.copyAsync(destFolder, destFileName, Windows.Storage.CreationCollisionOption.replaceExisting).done(success, error);
- }, error);
- }
- } else {
- // Copying file to persistent storage
- if (!destPath) {
- recordedFile.copyAsync(Windows.Storage.ApplicationData.current.localFolder, destFileName, Windows.Storage.CreationCollisionOption.replaceExisting).done(success, error);
- } else {
- Windows.Storage.ApplicationData.current.localFolder.getFolderAsync(destPath).done(function (destFolder) {
- recordedFile.copyAsync(destFolder, destFileName, Windows.Storage.CreationCollisionOption.replaceExisting).done(success, error);
- }, error);
- }
- }
- }, error);
- },
-
- // Release the media object
- release:function(win, lose, args) {
- var id = args[0];
- var thisM = Media.get(id);
- try {
- if (thisM.node) {
- thisM.node.onloadedmetadata = null;
- // Unsubscribing as the media object is being released
- thisM.node.onerror = null;
- // Needed to avoid "0x80070005 - JavaScript runtime error: Access is denied." on copyAsync
- thisM.node.src = null;
- delete thisM.node;
- }
- } catch (err) {
- lose("Failed to release: "+err);
- }
- },
- setVolume:function(win, lose, args) {
- var id = args[0];
- var volume = args[1];
- var thisM = Media.get(id);
- thisM.volume = volume;
- }
-};
-
-/**
- * Converts a path to Windows.Foundation.Uri basing on App data temporary folder
- * if scheme is not defined, e.g.: path/to/file.m4a -> ms-appdata:///temp/path/to/file.m4a
- * @param {String} src Input path
- * @return {Object} Windows.Foundation.Uri
- */
-function setTemporaryFsByDefault(src) {
- var uri;
- try {
- uri = new Windows.Foundation.Uri(src);
- } catch (e) {
- if (e.number === PARAMETER_IS_INCORRECT) {
- // Use TEMPORARY fs there is no 'scheme:'
- uri = new Windows.Foundation.Uri(tempFolderAppDataBasePath, src);
- } else {
- throw e;
- }
- } finally {
- return uri;
- }
-}
-
-/**
- * Convert native full path to ms-appdata path
- * @param {Object} uri Windows.Foundation.Uri
- * @return {Object} ms-appdata Windows.Foundation.Uri
- */
-function fullPathToAppData(uri) {
- if (uri.schemeName === 'file') {
- if (uri.rawUri.indexOf(Windows.Storage.ApplicationData.current.localFolder.path) !== -1) {
- // Also remove path' beginning slash to avoid losing folder name part
- uri = new Windows.Foundation.Uri(localFolderAppDataBasePath, uri.rawUri.replace(localFolderFullPath, '').replace(/^[\\\/]{1,2}/, ''));
- } else if (uri.rawUri.indexOf(Windows.Storage.ApplicationData.current.temporaryFolder.path) !== -1) {
- uri = new Windows.Foundation.Uri(tempFolderAppDataBasePath, uri.rawUri.replace(tempFolderFullPath, '').replace(/^[\\\/]{1,2}/, ''));
- } else {
- throw new Error('Not supported file uri: ' + uri.rawUri);
- }
- }
-
- return uri;
-}
-
-/**
- * Converts cdvfile paths to ms-appdata path
- * @param {Object} uri Input cdvfile scheme Windows.Foundation.Uri
- * @return {Object} Windows.Foundation.Uri based on App data path
- */
-function cdvfileToAppData(uri) {
- var cdvFsRoot;
-
- if (uri.schemeName === 'cdvfile') {
- cdvFsRoot = uri.path.split('/')[1];
- if (cdvFsRoot === 'temporary') {
- return new Windows.Foundation.Uri(tempFolderAppDataBasePath, uri.path.split('/').slice(2).join('/'));
- } else if (cdvFsRoot === 'persistent') {
- return new Windows.Foundation.Uri(localFolderAppDataBasePath, uri.path.split('/').slice(2).join('/'));
- } else {
- throw new Error(cdvFsRoot + ' cdvfile root is not supported on Windows');
- }
- }
-
- return uri;
-}
-
-/**
- * Prepares media src for internal usage
- * @param {String} src Input media path
- * @return {Object} Windows.Foundation.Uri
- */
-function processUri(src) {
- // Collapse double slashes (File plugin issue): ms-appdata:///temp//recs/memos/media.m4a => ms-appdata:///temp/recs/memos/media.m4a
- src = src.replace(/([^\/:])(\/\/)([^\/])/g, '$1/$3');
-
- // Remove beginning slashes
- src = src.replace(/^[\\\/]{1,2}/, '');
-
- var uri = setTemporaryFsByDefault(src);
-
- uri = fullPathToAppData(uri);
- uri = cdvfileToAppData(uri);
-
- return uri;
-}
-
-/**
- * Extracts path, filename and filesystem type from Uri
- * @param {Object} uri Windows.Foundation.Uri
- * @return {Object} Object containing path, filename and filesystem type
- */
-function parseUriToPathAndFilename(uri) {
- // Removing scheme and location, using backslashes: ms-appdata:///local/path/to/file.m4a -> path\\to\\file.m4a
- var normalizedSrc = uri.path.split('/').slice(2).join('\\');
-
- var path = normalizedSrc.substr(0, normalizedSrc.lastIndexOf('\\'));
- var fileName = normalizedSrc.replace(path + '\\', '');
-
- var fsType;
-
- if (uri.path.split('/')[1] === 'local') {
- fsType = fsTypes.PERSISTENT;
- } else if (uri.path.split('/')[1] === 'temp') {
- fsType = fsTypes.TEMPORARY;
- }
-
- return {
- path: path,
- fileName: fileName,
- fsType: fsType
- };
-}
-
-require("cordova/exec/proxy").add("Media",module.exports);
diff --git a/src/wp/AudioPlayer.cs b/src/wp/AudioPlayer.cs
deleted file mode 100644
index 273665142..000000000
--- a/src/wp/AudioPlayer.cs
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Threading;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Media;
-using Microsoft.Phone.Controls;
-using System.Diagnostics;
-using System.Windows.Resources;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
- ///
- /// Implements audio record and play back functionality.
- ///
- internal class AudioPlayer : IDisposable
- {
- #region Constants
-
- // AudioPlayer states
- private const int PlayerState_None = 0;
- private const int PlayerState_Starting = 1;
- private const int PlayerState_Running = 2;
- private const int PlayerState_Paused = 3;
- private const int PlayerState_Stopped = 4;
-
- // AudioPlayer messages
- private const int MediaState = 1;
- private const int MediaDuration = 2;
- private const int MediaPosition = 3;
- private const int MediaError = 9;
-
- // AudioPlayer errors
- private const int MediaErrorPlayModeSet = 1;
- private const int MediaErrorAlreadyRecording = 2;
- private const int MediaErrorStartingRecording = 3;
- private const int MediaErrorRecordModeSet = 4;
- private const int MediaErrorStartingPlayback = 5;
- private const int MediaErrorResumeState = 6;
- private const int MediaErrorPauseState = 7;
- private const int MediaErrorStopState = 8;
-
- //TODO: get rid of this callback, it should be universal
- //private const string CallbackFunction = "CordovaMediaonStatus";
-
- #endregion
-
-
- ///
- /// The AudioHandler object
- ///
- private Media handler;
-
- ///
- /// Temporary buffer to store audio chunk
- ///
- private byte[] buffer;
-
- ///
- /// Xna game loop dispatcher
- ///
- DispatcherTimer dtXna;
-
-
- ///
- /// Output buffer
- ///
- private MemoryStream memoryStream;
-
- ///
- /// The id of this player (used to identify Media object in JavaScript)
- ///
- private String id;
-
- ///
- /// State of recording or playback
- ///
- private int state = PlayerState_None;
-
- ///
- /// File name to play or record to
- ///
- private String audioFile = null;
-
- ///
- /// Duration of audio
- ///
- private double duration = -1;
-
- ///
- /// Audio player object
- ///
- private MediaElement player = null;
-
- ///
- /// Audio source
- ///
- private Microphone recorder;
-
- ///
- /// Internal flag specified that we should only open audio w/o playing it
- ///
- private bool prepareOnly = false;
-
- ///
- /// Creates AudioPlayer instance
- ///
- /// Media object
- /// player id
- public AudioPlayer(Media handler, String id)
- {
- this.handler = handler;
- this.id = id;
- }
-
-
- ///
- /// Destroys player and stop audio playing or recording
- ///
- public void Dispose()
- {
- if (this.player != null)
- {
- this.stopPlaying();
- this.player = null;
- }
- if (this.recorder != null)
- {
- this.stopRecording();
- this.recorder = null;
- }
-
- this.FinalizeXnaGameLoop();
- }
-
- private void InvokeCallback(int message, int value, bool removeHandler)
- {
- InvokeCallback(message, (double)value, removeHandler);
- }
-
- private void InvokeCallback(int message, double value, bool removeHandler)
- {
- var status = new Media.MediaStatus()
- {
- Id = this.id,
- MsgType = message
- };
-
- if (message == MediaError)
- {
- status.Value = new Media.MediaError() { Code = (int)value };
- }
- else
- {
- status.Value = value;
- }
-
- this.handler.ReportStatus(status);
- }
-
- ///
- /// Starts recording, data is stored in memory
- ///
- ///
- public void startRecording(string filePath)
- {
- if (this.player != null)
- {
- InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
- }
- else if (this.recorder == null)
- {
- try
- {
- this.audioFile = filePath;
- this.InitializeXnaGameLoop();
- this.recorder = Microphone.Default;
- this.recorder.BufferDuration = TimeSpan.FromMilliseconds(500);
- this.buffer = new byte[recorder.GetSampleSizeInBytes(this.recorder.BufferDuration)];
- this.recorder.BufferReady += new EventHandler(recorderBufferReady);
- MemoryStream stream = new MemoryStream();
- this.memoryStream = stream;
- int numBits = 16;
- int numBytes = numBits / 8;
-
- // inline version from AudioFormatsHelper
- stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
- stream.Write(BitConverter.GetBytes(0), 0, 4);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
- stream.Write(BitConverter.GetBytes(16), 0, 4);
- stream.Write(BitConverter.GetBytes((short)1), 0, 2);
- stream.Write(BitConverter.GetBytes((short)1), 0, 2);
- stream.Write(BitConverter.GetBytes(this.recorder.SampleRate), 0, 4);
- stream.Write(BitConverter.GetBytes(this.recorder.SampleRate * numBytes), 0, 4);
- stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
- stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
- stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
- stream.Write(BitConverter.GetBytes(0), 0, 4);
-
- this.recorder.Start();
- FrameworkDispatcher.Update();
- this.SetState(PlayerState_Running);
- }
- catch (Exception)
- {
- InvokeCallback(MediaError, MediaErrorStartingRecording, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingRecording),false);
- }
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorAlreadyRecording, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorAlreadyRecording),false);
- }
- }
-
- ///
- /// Stops recording
- ///
- public void stopRecording()
- {
- if (this.recorder != null)
- {
- if (this.state == PlayerState_Running)
- {
- try
- {
- this.recorder.Stop();
- this.recorder.BufferReady -= recorderBufferReady;
- this.recorder = null;
- SaveAudioClipToLocalStorage();
- this.FinalizeXnaGameLoop();
- this.SetState(PlayerState_Stopped);
- }
- catch (Exception)
- {
- //TODO
- }
- }
- }
- }
-
- ///
- /// Starts or resume playing audio file
- ///
- /// The name of the audio file
- ///
- /// Starts or resume playing audio file
- ///
- /// The name of the audio file
- public void startPlaying(string filePath)
- {
- if (this.recorder != null)
- {
- InvokeCallback(MediaError, MediaErrorRecordModeSet, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorRecordModeSet),false);
- return;
- }
-
-
- if (this.player == null || this.player.Source.AbsoluteUri.LastIndexOf(filePath) < 0)
- {
- try
- {
- // this.player is a MediaElement, it must be added to the visual tree in order to play
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
-
- this.player = grid.FindName("playerMediaElement") as MediaElement;
- if (this.player == null) // still null ?
- {
- this.player = new MediaElement();
- this.player.Name = "playerMediaElement";
- grid.Children.Add(this.player);
- this.player.Visibility = Visibility.Visible;
- }
- if (this.player.CurrentState == System.Windows.Media.MediaElementState.Playing)
- {
- this.player.Stop(); // stop it!
- }
-
- this.player.Source = null; // Garbage collect it.
- this.player.MediaOpened += MediaOpened;
- this.player.MediaEnded += MediaEnded;
- this.player.MediaFailed += MediaFailed;
- }
- }
- }
-
- this.audioFile = filePath;
-
- Uri uri = new Uri(filePath, UriKind.RelativeOrAbsolute);
- if (uri.IsAbsoluteUri)
- {
- this.player.Source = uri;
- }
- else
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- // try to unpack it from the dll into isolated storage
- StreamResourceInfo fileResourceStreamInfo = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));
- if (fileResourceStreamInfo != null)
- {
- using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
- {
- byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
-
- string[] dirParts = filePath.Split('/');
- string dirName = "";
- for (int n = 0; n < dirParts.Length - 1; n++)
- {
- dirName += dirParts[n] + "/";
- }
- if (!isoFile.DirectoryExists(dirName))
- {
- isoFile.CreateDirectory(dirName);
- }
-
- using (IsolatedStorageFileStream outFile = isoFile.OpenFile(filePath, FileMode.Create))
- {
- using (BinaryWriter writer = new BinaryWriter(outFile))
- {
- writer.Write(data);
- }
- }
- }
- }
- }
- if (isoFile.FileExists(filePath))
- {
- using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, isoFile))
- {
- this.player.SetSource(stream);
- }
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, 1), false);
- return;
- }
- }
- }
- this.SetState(PlayerState_Starting);
- }
- catch (Exception e)
- {
- Debug.WriteLine("Error in AudioPlayer::startPlaying : " + e.Message);
- InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingPlayback),false);
- }
- }
- else
- {
- if (this.state != PlayerState_Running)
- {
- this.player.Play();
- this.SetState(PlayerState_Running);
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorResumeState, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorResumeState),false);
- }
- }
- }
-
- ///
- /// Callback to be invoked when the media source is ready for playback
- ///
- private void MediaOpened(object sender, RoutedEventArgs arg)
- {
- if (this.player != null)
- {
- this.duration = this.player.NaturalDuration.TimeSpan.TotalSeconds;
- InvokeCallback(MediaDuration, this.duration, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaDuration, this.duration),false);
- if (!this.prepareOnly)
- {
- this.player.Play();
- this.SetState(PlayerState_Running);
- }
- this.prepareOnly = false;
- }
- else
- {
- // TODO: occasionally MediaOpened is signalled, but player is null
- }
- }
-
- ///
- /// Callback to be invoked when playback of a media source has completed
- ///
- private void MediaEnded(object sender, RoutedEventArgs arg)
- {
- this.SetState(PlayerState_Stopped);
- }
-
- ///
- /// Callback to be invoked when playback of a media source has failed
- ///
- private void MediaFailed(object sender, RoutedEventArgs arg)
- {
- if (player != null)
- {
- player.Stop();
- }
- InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError.ToString(), "Media failed"),false);
- }
-
- ///
- /// Seek or jump to a new time in the track
- ///
- /// The new track position
- public void seekToPlaying(int milliseconds)
- {
- if (this.player != null)
- {
- TimeSpan tsPos = new TimeSpan(0, 0, 0, 0, milliseconds);
- this.player.Position = tsPos;
- InvokeCallback(MediaPosition, milliseconds / 1000.0f, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, milliseconds / 1000.0f),false);
- }
- }
-
- ///
- /// Set the volume of the player
- ///
- /// volume 0.0-1.0, default value is 0.5
- public void setVolume(double vol)
- {
- if (this.player != null)
- {
- this.player.Volume = vol;
- }
- }
-
- ///
- /// Pauses playing
- ///
- public void pausePlaying()
- {
- if (this.state == PlayerState_Running)
- {
- this.player.Pause();
- this.SetState(PlayerState_Paused);
- }
- else
- {
- InvokeCallback(MediaError, MediaErrorPauseState, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorPauseState),false);
- }
- }
-
-
- ///
- /// Stops playing the audio file
- ///
- public void stopPlaying()
- {
- if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
- {
- this.player.Stop();
-
- this.player.Position = new TimeSpan(0L);
- this.SetState(PlayerState_Stopped);
- }
- //else // Why is it an error to call stop on a stopped media?
- //{
- // this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStopState), false);
- //}
- }
-
- ///
- /// Gets current position of playback
- ///
- /// current position
- public double getCurrentPosition()
- {
- if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
- {
- double currentPosition = this.player.Position.TotalSeconds;
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, currentPosition),false);
- return currentPosition;
- }
- else
- {
- return 0;
- }
- }
-
- ///
- /// Gets the duration of the audio file
- ///
- /// The name of the audio file
- /// track duration
- public double getDuration(string filePath)
- {
- if (this.recorder != null)
- {
- return (-2);
- }
-
- if (this.player != null)
- {
- return this.duration;
-
- }
- else
- {
- this.prepareOnly = true;
- this.startPlaying(filePath);
- return this.duration;
- }
- }
-
- ///
- /// Sets the state and send it to JavaScript
- ///
- /// state
- private void SetState(int state)
- {
- if (this.state != state)
- {
- InvokeCallback(MediaState, state, false);
- //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaState, state),false);
- }
-
- this.state = state;
- }
-
- #region record methods
-
- ///
- /// Copies data from recorder to memory storages and updates recording state
- ///
- ///
- ///
- private void recorderBufferReady(object sender, EventArgs e)
- {
- this.recorder.GetData(this.buffer);
- this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
- }
-
- ///
- /// Writes audio data from memory to isolated storage
- ///
- ///
- private void SaveAudioClipToLocalStorage()
- {
- if (memoryStream == null || memoryStream.Length <= 0)
- {
- return;
- }
-
- long position = memoryStream.Position;
- memoryStream.Seek(4, SeekOrigin.Begin);
- memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 8), 0, 4);
- memoryStream.Seek(40, SeekOrigin.Begin);
- memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 44), 0, 4);
- memoryStream.Seek(position, SeekOrigin.Begin);
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- string directory = Path.GetDirectoryName(audioFile);
-
- if (!isoFile.DirectoryExists(directory))
- {
- isoFile.CreateDirectory(directory);
- }
-
- this.memoryStream.Seek(0, SeekOrigin.Begin);
-
- using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(audioFile))
- {
- this.memoryStream.CopyTo(fileStream);
- }
- }
- }
- catch (Exception)
- {
- //TODO: log or do something else
- throw;
- }
- }
-
- #region Xna loop
- ///
- /// Special initialization required for the microphone: XNA game loop
- ///
- private void InitializeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- this.dtXna = new DispatcherTimer();
- this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
- this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
- this.dtXna.Start();
- }
- ///
- /// Finalizes XNA game loop for microphone
- ///
- private void FinalizeXnaGameLoop()
- {
- // Timer to simulate the XNA game loop (Microphone is from XNA)
- if (this.dtXna != null)
- {
- this.dtXna.Stop();
- this.dtXna = null;
- }
- }
-
- #endregion
-
- #endregion
- }
-}
diff --git a/src/wp/Media.cs b/src/wp/Media.cs
deleted file mode 100644
index b0d85b2bb..000000000
--- a/src/wp/Media.cs
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- ///
- /// Provides the ability to record and play back audio files on a device.
- ///
- public class Media : BaseCommand
- {
- ///
- /// Audio player objects
- ///
- private static Dictionary players = new Dictionary();
-
- ///
- /// Callback id for Media events channel
- ///
- private static string messageChannelCallbackId;
-
- ///
- /// Represents Media action options.
- ///
- [DataContract]
- public class MediaOptions
- {
- ///
- /// Audio id
- ///
- [DataMember(Name = "id", IsRequired = true)]
- public string Id { get; set; }
-
- ///
- /// Path to audio file
- ///
- [DataMember(Name = "src")]
- public string Src { get; set; }
-
- ///
- /// New track position
- ///
- [DataMember(Name = "milliseconds")]
- public int Milliseconds { get; set; }
-
- public string CallbackId { get; set; }
- }
-
- ///
- /// Reperesent media channel status changed action
- ///
- [DataContract]
- public class MediaChannelStatusAction
- {
- ///
- /// Action type
- ///
- [DataMember(Name = "action", IsRequired = true)]
- public string Action { get; set; }
-
- ///
- /// Status data
- ///
- [DataMember(Name = "status", IsRequired = true)]
- public MediaStatus Status { get; set; }
-
- ///
- /// Initialize a new instance
- ///
- public MediaChannelStatusAction()
- {
- this.Action = "status";
- }
- }
-
- ///
- /// Represents Media error
- ///
- [DataContract]
- public class MediaError
- {
- [DataMember(Name = "code", IsRequired = true)]
- public int Code { get; set; }
- }
-
- ///
- /// Represents Media status
- ///
- [DataContract]
- [KnownType(typeof(MediaError))]
- public class MediaStatus
- {
- ///
- /// Audio player Id
- ///
- [DataMember(Name = "id", IsRequired = true)]
- public string Id { get; set; }
-
- ///
- /// Status message type
- ///
- [DataMember(Name = "msgType", IsRequired = true)]
- public int MsgType { get; set; }
-
- ///
- /// Status message value
- ///
- [DataMember(Name = "value")]
- public dynamic Value { get; set; }
- }
-
- ///
- /// Establish channel for Media events
- ///
- public void messageChannel(string options)
- {
- string[] optionsString = JSON.JsonHelper.Deserialize(options);
- messageChannelCallbackId = optionsString[0];
- }
-
- ///
- /// Report Media status to JS
- ///
- public void ReportStatus(MediaStatus status)
- {
- PluginResult result = new PluginResult(PluginResult.Status.OK, new MediaChannelStatusAction() { Status = status });
- result.KeepCallback = true;
-
- DispatchCommandResult(result, messageChannelCallbackId);
- }
-
- ///
- /// Releases the audio player instance to save memory.
- ///
- public void release(string options)
- {
- string callbackId = this.CurrentCommandCallbackId;
- try
- {
- MediaOptions mediaOptions = new MediaOptions();
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize(options);
- mediaOptions.Id = optionsString[0];
- callbackId = mediaOptions.CallbackId = optionsString[1];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
-
- if (!Media.players.ContainsKey(mediaOptions.Id))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, false), callbackId);
- return;
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer audio = Media.players[mediaOptions.Id];
- Media.players.Remove(mediaOptions.Id);
- audio.Dispose();
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true), mediaOptions.CallbackId);
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), mediaOptions.CallbackId);
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
- }
- }
-
- private AudioPlayer GetOrCreatePlayerById(string id)
- {
- AudioPlayer audio = null;
-
- lock (Media.players)
- {
- if (!Media.players.TryGetValue(id, out audio))
- {
- audio = new AudioPlayer(this, id);
- Media.players.Add(id, audio);
- Debug.WriteLine("Media Created in GetOrCreatePlayerById");
- }
- }
-
-
-
- return audio;
- }
-
- ///
- /// Starts recording and save the specified file
- ///
- public void startRecordingAudio(string options)
- {
- string callbackId = this.CurrentCommandCallbackId;
- try
- {
- MediaOptions mediaOptions = new MediaOptions();
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize(options);
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- callbackId = mediaOptions.CallbackId = optionsString[2];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), mediaOptions.CallbackId);
- return;
- }
-
- if (mediaOptions != null)
- {
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer audio;
- if (!Media.players.ContainsKey(mediaOptions.Id))
- {
- audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- }
- else
- {
- audio = Media.players[mediaOptions.Id];
- }
-
- if (audio != null)
- {
- audio.startRecording(mediaOptions.Src);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK), mediaOptions.CallbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
- "Error accessing AudioPlayer for key " + mediaOptions.Id), mediaOptions.CallbackId);
- }
-
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), mediaOptions.CallbackId);
- }
-
- });
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), mediaOptions.CallbackId);
- }
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
- }
- }
-
- ///
- /// Stops recording and save to the file specified when recording started
- ///
- public void stopRecordingAudio(string options)
- {
- string callbackId = this.CurrentCommandCallbackId;
-
- try
- {
- string[] optStrings = JSON.JsonHelper.Deserialize(options);
- string mediaId = optStrings[0];
- callbackId = optStrings[1];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.stopRecording();
- Media.players.Remove(mediaId);
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
- }
- });
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- }
- }
-
- public void setVolume(string options) // id,volume
- {
- string callbackId = this.CurrentCommandCallbackId;
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize(options);
- string id = optionsString[0];
- double volume = 0.0d;
- double.TryParse(optionsString[1], out volume);
-
- callbackId = optionsString[2];
-
- if (Media.players.ContainsKey(id))
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- AudioPlayer player = Media.players[id];
- player.setVolume(volume);
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
- }
- });
- }
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION,
- "Error parsing options into setVolume method"), callbackId);
- }
- }
-
- // Some Audio Notes:
- // In the Windows Phone Emulator, playback of video or audio content using the MediaElement control is not supported.
- // While playing, a MediaElement stops all other media playback on the phone.
- // Multiple MediaElement controls are NOT supported
-
- // Called when you create a new Media('blah.wav') object in JS.
- public void create(string options)
- {
- string callbackId = this.CurrentCommandCallbackId;
- try
- {
- MediaOptions mediaOptions;
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- callbackId = mediaOptions.CallbackId = optionsString[2];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION,
- "Error parsing options into create method"), callbackId);
- return;
- }
-
- GetOrCreatePlayerById(mediaOptions.Id);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
-
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
- }
- }
-
- ///
- /// Starts or resume playing audio file
- ///
- public void startPlayingAudio(string options)
- {
- string callbackId = this.CurrentCommandCallbackId;
- try
- {
- MediaOptions mediaOptions;
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- int msec = 0;
- if (int.TryParse(optionsString[2], out msec))
- {
- mediaOptions.Milliseconds = msec;
- }
- callbackId = mediaOptions.CallbackId = optionsString[3];
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
-
- AudioPlayer audio = GetOrCreatePlayerById(mediaOptions.Id);
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- audio.startPlaying(mediaOptions.Src);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
- }
- }
-
-
- ///
- /// Seeks to a location
- ///
- public void seekToAudio(string options)
- {
- string callbackId = this.CurrentCommandCallbackId;
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize(options);
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- int msec = 0;
- if (int.TryParse(optionsString[1], out msec))
- {
- mediaOptions.Milliseconds = msec;
- }
- callbackId = mediaOptions.CallbackId = optionsString[2];
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaOptions.Id))
- {
- AudioPlayer audio = Media.players[mediaOptions.Id];
- audio.seekToPlaying(mediaOptions.Milliseconds);
- }
- else
- {
- Debug.WriteLine("ERROR: seekToAudio could not find mediaPlayer for " + mediaOptions.Id);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
- }
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
- }
- }
-
- ///
- /// Pauses playing
- ///
- public void pausePlayingAudio(string options)
- {
- string callbackId = this.CurrentCommandCallbackId;
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize(options);
- string mediaId = optionsString[0];
- callbackId = optionsString[1];
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.pausePlaying();
- }
- else
- {
- Debug.WriteLine("ERROR: pausePlayingAudio could not find mediaPlayer for " + mediaId);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message),callbackId);
- }
- });
-
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- }
-
-
- }
-
-
- ///
- /// Stops playing the audio file
- ///
- public void stopPlayingAudio(String options)
- {
- string callbackId = this.CurrentCommandCallbackId;
- try
- {
- string[] optionsStrings = JSON.JsonHelper.Deserialize(options);
- string mediaId = optionsStrings[0];
- callbackId = optionsStrings[1];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- audio.stopPlaying();
- }
- else
- {
- Debug.WriteLine("stopPlaying could not find mediaPlayer for " + mediaId);
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
- }
- });
-
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- }
- }
-
- ///
- /// Gets current position of playback
- ///
- public void getCurrentPositionAudio(string options)
- {
- string callbackId = this.CurrentCommandCallbackId;
- try
- {
- string[] optionsStrings = JSON.JsonHelper.Deserialize(options);
- string mediaId = optionsStrings[0];
- callbackId = optionsStrings[1];
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- try
- {
- if (Media.players.ContainsKey(mediaId))
- {
- AudioPlayer audio = Media.players[mediaId];
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getCurrentPosition()), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, -1), callbackId);
- }
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
- }
- });
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
- }
-
-
- ///
- /// Gets the duration of the audio file
- ///
-
- [Obsolete("This method will be removed shortly")]
- public void getDurationAudio(string options)
- {
- string callbackId = this.CurrentCommandCallbackId;
- try
- {
- MediaOptions mediaOptions;
-
- try
- {
- string[] optionsString = JSON.JsonHelper.Deserialize(options);
-
- mediaOptions = new MediaOptions();
- mediaOptions.Id = optionsString[0];
- mediaOptions.Src = optionsString[1];
- callbackId = mediaOptions.CallbackId = optionsString[2];
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
-
- AudioPlayer audio;
- if (Media.players.ContainsKey(mediaOptions.Id))
- {
- audio = Media.players[mediaOptions.Id];
- }
- else
- {
- Debug.WriteLine("ERROR: getDurationAudio could not find mediaPlayer for " + mediaOptions.Id);
- audio = new AudioPlayer(this, mediaOptions.Id);
- Media.players.Add(mediaOptions.Id, audio);
- }
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getDuration(mediaOptions.Src)), callbackId);
- });
- }
- catch (Exception e)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
- }
- }
- }
-}
diff --git a/tests/package.json b/tests/package.json
new file mode 100644
index 000000000..59fa0058b
--- /dev/null
+++ b/tests/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "cordova-plugin-media-tests",
+ "version": "7.0.1-dev",
+ "description": "",
+ "cordova": {
+ "id": "cordova-plugin-media-tests",
+ "platforms": []
+ },
+ "keywords": [
+ "ecosystem:cordova"
+ ],
+ "author": "",
+ "license": "Apache-2.0"
+}
diff --git a/tests/plugin.xml b/tests/plugin.xml
index 4c5c2c288..fec5f5662 100644
--- a/tests/plugin.xml
+++ b/tests/plugin.xml
@@ -19,10 +19,9 @@
-->
+ version="7.0.1-dev">
Cordova Media Plugin Tests
Apache 2.0
diff --git a/tests/tests.js b/tests/tests.js
index fa283d996..60414a9bb 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -19,28 +19,38 @@
*
*/
-/* jshint jasmine: true */
-/* global Windows, Media, MediaError, LocalFileSystem, halfSpeedBtn */
+/* global cordova, Media, MediaError, halfSpeedBtn */
// increased timeout for actual playback to give device chance to download and play mp3 file
// some emulators can be REALLY slow at this, so two minutes
var ACTUAL_PLAYBACK_TEST_TIMEOUT = 2 * 60 * 1000;
+jasmine.DEFAULT_TIMEOUT_INTERVAL = ACTUAL_PLAYBACK_TEST_TIMEOUT;
-var WEB_MP3_FILE = 'https://cordova.apache.org/downloads/BlueZedEx.mp3';
-var WEB_MP3_STREAM = 'http://c22033-l.i.core.cdn.streamfarm.net/22033mdr/live/3087mdr_figaro/ch_classic_128.mp3';
+var WEB_MP3_FILE = 'https://cordova.apache.org/static/downloads/BlueZedEx.mp3';
+var WEB_MP3_STREAM = 'https://cordova.apache.org/static/downloads/BlueZedEx.mp3';
-var isWindows = cordova.platformId == 'windows8' || cordova.platformId == 'windows';
+var isBrowser = cordova.platformId === 'browser';
// Detect whether audio hardware is available and enabled. For iOS playing audio is
// not supported on emulators w/out sound device connected to host PC but (which is
// the case for Sauce Labs emulators - see CB-11430)
-var isAudioSupported = isWindows ? !!Windows.Media.Devices.MediaDevice.getDefaultAudioRenderId(Windows.Media.Devices.AudioDeviceRole.default) :
- cordova.platformId === 'ios' ? !window.SAUCELABS_ENV : true;
+var isAudioSupported = cordova.platformId === 'ios'
+ ? !window.SAUCELABS_ENV
+ : true;
+
+// Detect OS version when running on Android
+var androidVersion = null;
+if (cordova.platformId === 'android') {
+ var ua = navigator.userAgent;
+ var androidStart = ua.indexOf('Android ');
+ var versionString = ua.substring(androidStart + 8, ua.indexOf(';', androidStart));
+ androidVersion = versionString.split('.').map(function (x) { return x / 1; });
+}
exports.defineAutoTests = function () {
var failed = function (done, msg, context) {
if (context && context.done) return;
context.done = true;
- var info = typeof msg == 'undefined' ? 'Unexpected error callback' : msg;
+ var info = typeof msg === 'undefined' ? 'Unexpected error callback' : msg;
expect(true).toFailWithMessage(info);
done();
};
@@ -48,23 +58,22 @@ exports.defineAutoTests = function () {
var succeed = function (done, msg, context) {
if (context && context.done) return;
context.done = true;
- var info = typeof msg == 'undefined' ? 'Unexpected success callback' : msg;
+ var info = typeof msg === 'undefined' ? 'Unexpected success callback' : msg;
expect(true).toFailWithMessage(info);
done();
};
describe('Media', function () {
-
beforeEach(function () {
// Custom Matcher
jasmine.Expectation.addMatchers({
- toFailWithMessage : function () {
+ toFailWithMessage: function () {
return {
- compare : function (error, message) {
+ compare: function (_, message) {
var pass = false;
return {
- pass : pass,
- message : message
+ pass,
+ message
};
}
};
@@ -72,13 +81,13 @@ exports.defineAutoTests = function () {
});
});
- it("media.spec.1 should exist", function () {
+ it('media.spec.1 should exist', function () {
expect(Media).toBeDefined();
- expect(typeof Media).toBe("function");
+ expect(typeof Media).toBe('function');
});
- it("media.spec.2 should have the following properties", function () {
- var media1 = new Media("dummy");
+ it('media.spec.2 should have the following properties', function () {
+ var media1 = new Media('dummy');
expect(media1.id).toBeDefined();
expect(media1.src).toBeDefined();
expect(media1._duration).toBeDefined();
@@ -86,7 +95,7 @@ exports.defineAutoTests = function () {
media1.release();
});
- it("media.spec.3 should define constants for Media status", function () {
+ it('media.spec.3 should define constants for Media status', function () {
expect(Media).toBeDefined();
expect(Media.MEDIA_NONE).toBe(0);
expect(Media.MEDIA_STARTING).toBe(1);
@@ -95,7 +104,7 @@ exports.defineAutoTests = function () {
expect(Media.MEDIA_STOPPED).toBe(4);
});
- it("media.spec.4 should define constants for Media errors", function () {
+ it('media.spec.4 should define constants for Media errors', function () {
expect(MediaError).toBeDefined();
expect(MediaError.MEDIA_ERR_NONE_ACTIVE).toBe(0);
expect(MediaError.MEDIA_ERR_ABORTED).toBe(1);
@@ -104,106 +113,108 @@ exports.defineAutoTests = function () {
expect(MediaError.MEDIA_ERR_NONE_SUPPORTED).toBe(4);
});
- it("media.spec.5 should contain a play function", function () {
- var media1 = new Media("dummy");
+ it('media.spec.5 should contain a play function', function () {
+ var media1 = new Media('dummy');
expect(media1.play).toBeDefined();
expect(typeof media1.play).toBe('function');
media1.release();
});
- it("media.spec.6 should contain a stop function", function () {
- var media1 = new Media("dummy");
+ it('media.spec.6 should contain a stop function', function () {
+ var media1 = new Media('dummy');
expect(media1.stop).toBeDefined();
expect(typeof media1.stop).toBe('function');
media1.release();
});
- it("media.spec.7 should contain a seekTo function", function () {
- var media1 = new Media("dummy");
+ it('media.spec.7 should contain a seekTo function', function () {
+ var media1 = new Media('dummy');
expect(media1.seekTo).toBeDefined();
expect(typeof media1.seekTo).toBe('function');
media1.release();
});
- it("media.spec.8 should contain a pause function", function () {
- var media1 = new Media("dummy");
+ it('media.spec.8 should contain a pause function', function () {
+ var media1 = new Media('dummy');
expect(media1.pause).toBeDefined();
expect(typeof media1.pause).toBe('function');
media1.release();
});
- it("media.spec.9 should contain a getDuration function", function () {
- var media1 = new Media("dummy");
+ it('media.spec.9 should contain a getDuration function', function () {
+ var media1 = new Media('dummy');
expect(media1.getDuration).toBeDefined();
expect(typeof media1.getDuration).toBe('function');
media1.release();
});
- it("media.spec.10 should contain a getCurrentPosition function", function () {
- var media1 = new Media("dummy");
+ it('media.spec.10 should contain a getCurrentPosition function', function () {
+ var media1 = new Media('dummy');
expect(media1.getCurrentPosition).toBeDefined();
expect(typeof media1.getCurrentPosition).toBe('function');
media1.release();
});
- it("media.spec.11 should contain a startRecord function", function () {
- var media1 = new Media("dummy");
+ it('media.spec.11 should contain a startRecord function', function () {
+ var media1 = new Media('dummy');
expect(media1.startRecord).toBeDefined();
expect(typeof media1.startRecord).toBe('function');
media1.release();
});
- it("media.spec.12 should contain a stopRecord function", function () {
- var media1 = new Media("dummy");
+ it('media.spec.12 should contain a stopRecord function', function () {
+ var media1 = new Media('dummy');
expect(media1.stopRecord).toBeDefined();
expect(typeof media1.stopRecord).toBe('function');
media1.release();
});
- it("media.spec.13 should contain a release function", function () {
- var media1 = new Media("dummy");
+ it('media.spec.13 should contain a release function', function () {
+ var media1 = new Media('dummy');
expect(media1.release).toBeDefined();
expect(typeof media1.release).toBe('function');
media1.release();
});
- it("media.spec.14 should contain a setVolume function", function () {
- var media1 = new Media("dummy");
+ it('media.spec.14 should contain a setVolume function', function () {
+ var media1 = new Media('dummy');
expect(media1.setVolume).toBeDefined();
expect(typeof media1.setVolume).toBe('function');
media1.release();
});
- it("media.spec.15 should contain a getCurrentAmplitude function", function () {
- var media1 = new Media("dummy");
+ it('media.spec.15 should contain a getCurrentAmplitude function', function () {
+ var media1 = new Media('dummy');
expect(media1.getCurrentAmplitude).toBeDefined();
expect(typeof media1.getCurrentAmplitude).toBe('function');
media1.release();
});
- it("media.spec.16 should contain a pauseRecord function", function () {
- var media1 = new Media("dummy");
+ it('media.spec.16 should contain a pauseRecord function', function () {
+ var media1 = new Media('dummy');
expect(media1.pauseRecord).toBeDefined();
expect(typeof media1.pauseRecord).toBe('function');
media1.release();
});
- it("media.spec.17 should contain a resumeRecord function", function () {
- var media1 = new Media("dummy");
+ it('media.spec.17 should contain a resumeRecord function', function () {
+ var media1 = new Media('dummy');
expect(media1.resumeRecord).toBeDefined();
expect(typeof media1.resumeRecord).toBe('function');
media1.release();
});
- it("media.spec.18 should return MediaError for bad filename", function (done) {
- //bb10 dialog pops up, preventing tests from running
- if (cordova.platformId === 'blackberry10') {
- pending();
- }
-
- var context = this,
- fileName = 'invalid.file.name',
- badMedia = new Media(fileName, succeed.bind(null, done, ' badMedia = new Media , Unexpected succees callback, it should not create Media object with invalid file name'), function (result) {
+ it('media.spec.18 should return MediaError for bad filename', function (done) {
+ var context = this;
+ var fileName = 'invalid.file.name';
+ var badMedia = new Media(
+ fileName,
+ succeed.bind(
+ null,
+ done,
+ ' badMedia = new Media , Unexpected succees callback, it should not create Media object with invalid file name'
+ ),
+ function (result) {
if (context.done) return;
context.done = true;
@@ -213,40 +224,69 @@ exports.defineAutoTests = function () {
badMedia.release();
}
done();
- });
+ }
+ );
badMedia.play();
});
- describe('actual playback', function() {
- var checkInterval,
- media;
+ it("media.spec.19 MediaError instance should contain 'code' and 'message' fields", function (done) {
+ var context = this;
+ var fileName = 'invalid.file.name';
+ var badMedia = new Media(fileName, succeed.bind(null, done, ' badMedia = new Media , Unexpected succees callback, it should not create Media object with invalid file name'), function (result) {
+ if (context.done) return;
+ context.done = true;
+ expect(result).toBeDefined();
+ expect(result.code).toBeDefined();
+ expect(result.message).toBeDefined();
+ if (badMedia) {
+ badMedia.release();
+ }
+ done();
+ });
+ badMedia.play();
+ });
+
+ describe('actual playback', function () {
+ var checkInterval, media;
+
+ // Ensure interval and media is cleared out before and after each test
+ var safeDone = function () {
+ if (checkInterval) {
+ clearInterval(checkInterval);
+ checkInterval = null;
+ }
- afterEach(function() {
- clearInterval(checkInterval);
if (media) {
media.stop();
media.release();
media = null;
}
- });
+ };
- it("media.spec.19 position should be set properly", function (done) {
- // no audio hardware available
- if (!isAudioSupported) {
- pending();
- }
+ afterEach(function () { safeDone(); });
+ beforeEach(function () { safeDone(); });
- //context variable used as an extra security statement to ensure that the callback is processed only once,
- //in case the statusChange callback is reached more than one time with the same status code.
- //Some information about this kind of behaviour can be found at JIRA: CB-7099.
- var context = this,
- mediaFile = WEB_MP3_FILE,
- successCallback = function () { },
- statusChange = function (statusCode) {
- if (!context.done && statusCode == Media.MEDIA_RUNNING) {
+ it(
+ 'media.spec.19 position should be set properly',
+ function (done) {
+ // no audio hardware available
+ if (!isAudioSupported || isBrowser) {
+ pending();
+ }
+
+ // context variable used as an extra security statement to ensure that the callback is processed only once,
+ // in case the statusChange callback is reached more than one time with the same status code.
+ // Some information about this kind of behaviour can be found at JIRA: CB-7099.
+ var context = this;
+ var mediaFile = WEB_MP3_FILE;
+ var successCallback = function () {
+ done();
+ };
+ var statusChange = function (statusCode) {
+ if (!context.done && statusCode === Media.MEDIA_RUNNING) {
checkInterval = setInterval(function () {
if (context.done) return;
- media.getCurrentPosition(function successCallback(position) {
+ media.getCurrentPosition(function successCallback (position) {
if (position > 0.0) {
context.done = true;
expect(true).toBe(true);
@@ -256,23 +296,34 @@ exports.defineAutoTests = function () {
}, 1000);
}
};
- media = new Media(mediaFile, successCallback, failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context), statusChange);
- media.play();
- }, ACTUAL_PLAYBACK_TEST_TIMEOUT);
-
- it("media.spec.20 duration should be set properly", function (done) {
- if (!isAudioSupported || cordova.platformId === 'blackberry10') {
- pending();
- }
+ media = new Media(
+ mediaFile,
+ successCallback,
+ failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context),
+ statusChange
+ );
+ media.play();
+ },
+ ACTUAL_PLAYBACK_TEST_TIMEOUT
+ );
+
+ it(
+ 'media.spec.20 duration should be set properly',
+ function (done) {
+ if (!isAudioSupported || isBrowser) {
+ pending();
+ }
- //context variable used as an extra security statement to ensure that the callback is processed only once,
- //in case the statusChange callback is reached more than one time with the same status code.
- //Some information about this kind of behaviour can be found at JIRA: CB-7099.
- var context = this,
- mediaFile = WEB_MP3_FILE,
- successCallback = function () { },
- statusChange = function (statusCode) {
- if (!context.done && statusCode == Media.MEDIA_RUNNING) {
+ // context variable used as an extra security statement to ensure that the callback is processed only once,
+ // in case the statusChange callback is reached more than one time with the same status code.
+ // Some information about this kind of behaviour can be found at JIRA: CB-7099.
+ var context = this;
+ var mediaFile = WEB_MP3_FILE;
+ var successCallback = function () {
+ done();
+ };
+ var statusChange = function (statusCode) {
+ if (!context.done && statusCode === Media.MEDIA_RUNNING) {
checkInterval = setInterval(function () {
if (context.done) return;
media.getCurrentPosition(function (position) {
@@ -285,96 +336,156 @@ exports.defineAutoTests = function () {
}, 1000);
}
};
- media = new Media(mediaFile, successCallback, failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context), statusChange);
- media.play();
- }, ACTUAL_PLAYBACK_TEST_TIMEOUT);
-
- it("media.spec.21 should be able to resume playback after pause", function (done) {
- if (!isAudioSupported || cordova.platformId === 'blackberry10') {
- pending();
- }
-
- //context variable used as an extra security statement to ensure that the callback is processed only once,
- //in case the statusChange callback is reached more than one time with the same status code.
- //Some information about this kind of behaviour can be found at JIRA: CB-7099.
- var context = this;
- var resumed = false;
- var mediaFile = WEB_MP3_FILE;
- var successCallback = function () { };
- var statusChange = function (statusCode) {
- if (context.done) return;
-
- if (statusCode == Media.MEDIA_RUNNING) {
- if (!resumed) {
- media.seekTo(20000);
- media.pause();
- return;
- }
-
- media.getCurrentPosition(function (position) {
- expect(position).toBeCloseTo(20, 0);
- context.done = true;
- done();
- }, failed.bind(null, done, 'media1.getCurrentPosition - Error getting media current position', context));
- }
-
- if (statusCode == Media.MEDIA_PAUSED) {
- resumed = true;
- media.play();
- }
- };
- media = new Media(mediaFile, successCallback, failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context), statusChange);
-
- // CB-10535: Play after a few secs, to give allow enough buffering of media file before seeking
- setTimeout(function() {
+ media = new Media(
+ mediaFile,
+ successCallback,
+ failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context),
+ statusChange
+ );
media.play();
- }, 4000);
+ },
+ ACTUAL_PLAYBACK_TEST_TIMEOUT
+ );
+
+ it(
+ 'media.spec.21 should be able to resume playback after pause',
+ function (done) {
+ if (!isAudioSupported || isBrowser) {
+ /**
+ * Browser Error:
+ * Uncaught (in promise) DOMException: play() failed because the user didn't interact with
+ * the document first. https://goo.gl/xX8pDD
+ *
+ * The Autoplay Policy launched in Chrome 66 for audio and video elements and is effectively
+ * blocking roughly half of unwanted media autoplays in Chrome. For the Web Audio API, the
+ * autoplay policy launched in Chrome 71. This affects web games, some WebRTC applications,
+ * and other web pages using audio features. More details can be found in the Web Audio API
+ * section below.
+ *
+ * Due to the Chrome Policies, this test is disabled because it can not be run without user
+ * interations.
+ */
+ pending();
+ }
- }, ACTUAL_PLAYBACK_TEST_TIMEOUT);
+ // context variable used as an extra security statement to ensure that the callback is processed only once,
+ // in case the statusChange callback is reached more than one time with the same status code.
+ // Some information about this kind of behaviour can be found at JIRA: CB-7099.
+ var context = this;
+ var resumed = false;
+ var mediaFile = WEB_MP3_FILE;
+ var successCallback = function () {
+ done();
+ };
+ var statusChange = function (statusCode) {
+ if (context.done) return;
- it("media.spec.22 should be able to seek through file", function (done) {
- if (!isAudioSupported || cordova.platformId === 'blackberry10') {
- pending();
- }
+ if (statusCode === Media.MEDIA_RUNNING) {
+ if (!resumed) {
+ media.seekTo(20000);
+ media.pause();
+ return;
+ }
- //context variable used as an extra security statement to ensure that the callback is processed only once,
- //in case the statusChange callback is reached more than one time with the same status code.
- //Some information about this kind of behaviour can be found at JIRA: CB-7099.
- var context = this;
- var mediaFile = WEB_MP3_FILE;
- var successCallback = function () { };
- var statusChange = function (statusCode) {
- if (!context.done && statusCode == Media.MEDIA_RUNNING) {
- checkInterval = setInterval(function () {
- if (context.done) return;
- media.seekTo(5000);
media.getCurrentPosition(function (position) {
- expect(position).toBeCloseTo(5, 0);
+ expect(position).toBeGreaterThan(19);
+ expect(position).toBeLessThan(21);
context.done = true;
done();
}, failed.bind(null, done, 'media1.getCurrentPosition - Error getting media current position', context));
- }, 1000);
- }
- };
- media = new Media(mediaFile, successCallback, failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context), statusChange);
+ }
- // CB-10535: Play after a few secs, to give allow enough buffering of media file before seeking
- setTimeout(function() {
- media.play();
- }, 4000);
+ if (statusCode === Media.MEDIA_PAUSED) {
+ resumed = true;
+ media.play();
+ }
+ };
+ media = new Media(
+ mediaFile,
+ successCallback,
+ failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context),
+ statusChange
+ );
+
+ // CB-10535: Play after a few secs, to give allow enough buffering of media file before seeking
+ setTimeout(function () {
+ media.play();
+ }, 4000);
+ },
+ ACTUAL_PLAYBACK_TEST_TIMEOUT
+ );
+
+ it(
+ 'media.spec.22 should be able to seek through file',
+ function (done) {
+ if (!isAudioSupported || isBrowser) {
+ /**
+ * Browser Error:
+ * Uncaught (in promise) DOMException: play() failed because the user didn't interact with
+ * the document first. https://goo.gl/xX8pDD
+ *
+ * The Autoplay Policy launched in Chrome 66 for audio and video elements and is effectively
+ * blocking roughly half of unwanted media autoplays in Chrome. For the Web Audio API, the
+ * autoplay policy launched in Chrome 71. This affects web games, some WebRTC applications,
+ * and other web pages using audio features. More details can be found in the Web Audio API
+ * section below.
+ *
+ * Due to the Chrome Policies, this test is disabled because it can not be run without user
+ * interations.
+ */
+ pending();
+ }
- }, ACTUAL_PLAYBACK_TEST_TIMEOUT);
+ // context variable used as an extra security statement to ensure that the callback is processed only once,
+ // in case the statusChange callback is reached more than one time with the same status code.
+ // Some information about this kind of behaviour can be found at JIRA: CB-7099.
+ var context = this;
+ var mediaFile = WEB_MP3_FILE;
+ var successCallback = function () {
+ done();
+ };
+ var statusChange = function (statusCode) {
+ if (!context.done && statusCode === Media.MEDIA_RUNNING) {
+ checkInterval = setInterval(function () {
+ if (context.done) return;
+ media.seekTo(5000);
+ media.pause(); // pause media before confirming if it seeked to 5 seconds against current position.
+ media.getCurrentPosition(function (position) {
+ expect(position).toBeCloseTo(5, 0);
+ context.done = true;
+ done();
+ }, failed.bind(null, done, 'media1.getCurrentPosition - Error getting media current position', context));
+ }, 1000);
+ }
+ };
+ media = new Media(
+ mediaFile,
+ successCallback,
+ failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context),
+ statusChange
+ );
+
+ // CB-10535: Play after a few secs, to give allow enough buffering of media file before seeking
+ setTimeout(function () {
+ media.play();
+ }, 4000);
+ },
+ ACTUAL_PLAYBACK_TEST_TIMEOUT
+ );
});
- it("media.spec.23 should contain a setRate function", function () {
- var media1 = new Media("dummy");
+ it('media.spec.23 should contain a setRate function', function () {
+ var media1 = new Media('dummy');
expect(media1.setRate).toBeDefined();
expect(typeof media1.setRate).toBe('function');
media1.release();
});
- it("media.spec.24 playback rate should be set properly using setRate", function (done) {
- if (cordova.platformId !== 'ios') {
+ it('media.spec.24 playback rate should be set properly using setRate', function (done) {
+ if (
+ cordova.platformId !== 'ios' &&
+ (cordova.platformId !== 'android' || androidVersion[0] <= 6)
+ ) {
expect(true).toFailWithMessage('Platform does not supported this feature');
pending();
}
@@ -384,55 +495,67 @@ exports.defineAutoTests = function () {
pending();
}
- var mediaFile = WEB_MP3_FILE,
- successCallback,
- context = this,
- flag = true,
- statusChange = function (statusCode) {
- console.log("status code: " + statusCode);
- if (statusCode == Media.MEDIA_RUNNING && flag) {
- //flag variable used to ensure an extra security statement to ensure that the callback is processed only once,
- //in case for some reason the statusChange callback is reached more than one time with the same status code.
- //Some information about this kind of behavior it can be found at JIRA: CB-7099
- flag = false;
- setTimeout(function () {
- media1.getCurrentPosition(function (position) {
- //in four seconds expect position to be between 4 & 10. Here, the values are chosen to give
- //a large enough buffer range for the position to fall in and are not based on any calculation.
+ var mediaFile = WEB_MP3_FILE;
+ var successCallback;
+ var context = this;
+ var flag = true;
+ var statusChange = function (statusCode) {
+ console.log('status code: ' + statusCode);
+ if (statusCode === Media.MEDIA_RUNNING && flag) {
+ // flag variable used to ensure an extra security statement to ensure that the callback is processed only once,
+ // in case for some reason the statusChange callback is reached more than one time with the same status code.
+ // Some information about this kind of behavior it can be found at JIRA: CB-7099
+ flag = false;
+ setTimeout(function () {
+ media1.getCurrentPosition(
+ function (position) {
+ // in four seconds expect position to be between 4 & 10. Here, the values are chosen to give
+ // a large enough buffer range for the position to fall in and are not based on any calculation.
expect(position).not.toBeLessThan(4);
expect(position).toBeLessThan(10);
media1.stop();
media1.release();
context.done = true;
done();
- }, failed.bind(null, done, 'media1.getCurrentPosition - Error getting media current position'),context);
- }, 4000);
- }
- };
+ },
+ failed.bind(null, done, 'media1.getCurrentPosition - Error getting media current position'),
+ context
+ );
+ }, 4000);
+ }
+ };
- var media1 = new Media(mediaFile, successCallback, failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context), statusChange); // jshint ignore:line
- //make audio playback two times faster
+ var media1 = new Media(
+ mediaFile,
+ successCallback,
+ failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context),
+ statusChange
+ );
+ // make audio playback two times faster
media1.setRate(2);
media1.play();
}, ACTUAL_PLAYBACK_TEST_TIMEOUT);
- it("media.spec.25 should be able to play an audio stream", function (done) {
- // no audio hardware available
- if (!isAudioSupported) {
- pending();
- }
+ it(
+ 'media.spec.25 should be able to play an audio stream',
+ function (done) {
+ // no audio hardware available, OR
+ // O_o Safari can't play the stream, so we're skipping this test on all browsers o_O
+ if (!isAudioSupported || isBrowser) {
+ pending();
+ }
- // The link below points to an infinite mp3 stream
- var mediaFile = WEB_MP3_STREAM,
- successCallback,
- context = this,
- flag = true,
- statusChange = function (statusCode) {
- console.log("status code: " + statusCode);
- if (statusCode == Media.MEDIA_RUNNING && flag) {
- //flag variable used to ensure an extra security statement to ensure that the callback is processed only once,
- //in case for some reason the statusChange callback is reached more than one time with the same status code.
- //Some information about this kind of behavior it can be found at JIRA: CB-7099
+ // The link below points to an infinite mp3 stream
+ var mediaFile = WEB_MP3_STREAM;
+ var successCallback;
+ var context = this;
+ var flag = true;
+ var statusChange = function (statusCode) {
+ console.log('status code: ' + statusCode);
+ if (statusCode === Media.MEDIA_RUNNING && flag) {
+ // flag variable used to ensure an extra security statement to ensure that the callback is processed only once,
+ // in case for some reason the statusChange callback is reached more than one time with the same status code.
+ // Some information about this kind of behavior it can be found at JIRA: CB-7099
flag = false;
expect(true).toBe(true);
media1.stop();
@@ -442,16 +565,18 @@ exports.defineAutoTests = function () {
}
};
- var media1 = new Media(mediaFile, successCallback, failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context), statusChange); // jshint ignore:line
- media1.play();
- }, ACTUAL_PLAYBACK_TEST_TIMEOUT);
-
- it("media.spec.26 should not crash or throw when setting the volume right after creating the media", function (done) {
- //bb10 dialog pops up, preventing tests from running
- if (cordova.platformId === 'blackberry10') {
- pending();
- }
+ var media1 = new Media(
+ mediaFile,
+ successCallback,
+ failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile, context),
+ statusChange
+ );
+ media1.play();
+ },
+ ACTUAL_PLAYBACK_TEST_TIMEOUT
+ );
+ it('media.spec.26 should not crash or throw when setting the volume right after creating the media', function (done) {
var mediaFile = WEB_MP3_FILE;
var media = null;
@@ -469,9 +594,22 @@ exports.defineAutoTests = function () {
}, 3000);
});
- it("media.spec.27 should call success or error when trying to stop a media that is in starting state", function (done) {
- //bb10 dialog pops up, preventing tests from running
- if (!isAudioSupported || cordova.platformId === 'blackberry10') {
+ it('media.spec.27 should call success or error when trying to stop a media that is in starting state', function (done) {
+ if (!isAudioSupported || isBrowser) {
+ /**
+ * Browser Error:
+ * Uncaught (in promise) DOMException: play() failed because the user didn't interact with
+ * the document first. https://goo.gl/xX8pDD
+ *
+ * The Autoplay Policy launched in Chrome 66 for audio and video elements and is effectively
+ * blocking roughly half of unwanted media autoplays in Chrome. For the Web Audio API, the
+ * autoplay policy launched in Chrome 71. This affects web games, some WebRTC applications,
+ * and other web pages using audio features. More details can be found in the Web Audio API
+ * section below.
+ *
+ * Due to the Chrome Policies, this test is disabled because it can not be run without user
+ * interations.
+ */
pending();
}
@@ -488,7 +626,7 @@ exports.defineAutoTests = function () {
};
var errorCallback = jasmine.createSpy('errorCallback').and.callFake(function (e) {
- expect(beenStarting).toBe(true);
+ expect(true).toBe(true);
safeDone();
});
var successCallback = function () {
@@ -496,10 +634,10 @@ exports.defineAutoTests = function () {
safeDone();
};
var statusChange = function (s) {
- if ((s == Media.MEDIA_STARTING) && !context.done) {
+ if (s === Media.MEDIA_STARTING && !context.done) {
beenStarting = true;
media.stop();
- } else if (s == Media.MEDIA_RUNNING) {
+ } else if (s === Media.MEDIA_RUNNING) {
// Some plugin implementations may skip "Starting" state
// so we'll also try to call stop in "Running" state,
// but in this case we should check that the "Starting" state wasn't really reached,
@@ -512,27 +650,26 @@ exports.defineAutoTests = function () {
media = new Media(mediaFile, successCallback, errorCallback, statusChange);
media.play();
});
-
});
};
-//******************************************************************************************
-//***************************************Manual Tests***************************************
-//******************************************************************************************
+//* *****************************************************************************************
+//* **************************************Manual Tests***************************************
+//* *****************************************************************************************
exports.defineManualTests = function (contentEl, createActionButton) {
- //-------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// Audio player
- //-------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
var media1 = null;
var media1Timer = null;
var audioSrc = null;
var defaultaudio = WEB_MP3_FILE;
- //Play audio function
- function playAudio(url) {
- console.log("playAudio()");
- console.log(" -- media=" + media1);
+ // Play audio function
+ function playAudio (url) {
+ console.log('playAudio()');
+ console.log(' -- media=' + media1);
var src = defaultaudio;
@@ -549,84 +686,83 @@ exports.defineManualTests = function (contentEl, createActionButton) {
}
if (media1 === null) {
-
// TEST STREAMING AUDIO PLAYBACK
- //var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.mp3"; // works
- //var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.m3u"; // doesn't work
- //var src = "http://www.wav-sounds.com/cartoon/bugsbunny1.wav"; // works
- //var src = "http://www.angelfire.com/fl5/html-tutorial/a/couldyou.mid"; // doesn't work
- //var src = "MusicSearch/mp3/train.mp3"; // works
- //var src = "bryce.mp3"; // works
- //var src = "/android_asset/www/bryce.mp3"; // works
-
- media1 = new Media(src,
- function () {
- console.log("playAudio():Audio Success");
+ // var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.mp3"; // works
+ // var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.m3u"; // doesn't work
+ // var src = "http://www.wav-sounds.com/cartoon/bugsbunny1.wav"; // works
+ // var src = "http://www.angelfire.com/fl5/html-tutorial/a/couldyou.mid"; // doesn't work
+ // var src = "MusicSearch/mp3/train.mp3"; // works
+ // var src = "bryce.mp3"; // works
+ // var src = "/android_asset/www/bryce.mp3"; // works
+
+ media1 = new Media(
+ src,
+ function () {
+ console.log('playAudio():Audio Success');
},
- function (err) {
- console.log("playAudio():Audio Error: " + err.code);
- setAudioStatus("Error: " + err.code);
+ function (err) {
+ console.log('playAudio():Audio Error: ' + err.code);
+ setAudioStatus('Error: ' + err.code);
},
- function (status) {
- console.log("playAudio():Audio Status: " + status);
+ function (status) {
+ console.log('playAudio():Audio Status: ' + status);
setAudioStatus(Media.MEDIA_MSG[status]);
// If stopped, then stop getting current position
- if (Media.MEDIA_STOPPED == status) {
+ if (Media.MEDIA_STOPPED === status) {
clearInterval(media1Timer);
media1Timer = null;
- setAudioPosition("0 sec");
+ setAudioPosition('0 sec');
}
- });
+ }
+ );
}
audioSrc = src;
- document.getElementById('durationValue').innerHTML = "";
+ document.getElementById('durationValue').innerHTML = '';
// Play audio
media1.play();
if (media1Timer === null && media1.getCurrentPosition) {
- media1Timer = setInterval(
- function () {
- media1.getCurrentPosition(
- function (position) {
+ media1Timer = setInterval(function () {
+ media1.getCurrentPosition(
+ function (position) {
if (position >= 0.0) {
- setAudioPosition(position + " sec");
+ setAudioPosition(position + ' sec');
}
},
- function (e) {
- console.log("Error getting pos=" + e);
- setAudioPosition("Error: " + e);
- });
- },
- 1000);
+ function (e) {
+ console.log('Error getting pos=' + e);
+ setAudioPosition('Error: ' + e);
+ }
+ );
+ }, 1000);
}
// Get duration
var counter = 0;
- var timerDur = setInterval(
- function () {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = media1.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('durationValue').innerHTML = dur + " sec";
- }
- }, 100);
+ var timerDur = setInterval(function () {
+ counter = counter + 100;
+ if (counter > 2000) {
+ clearInterval(timerDur);
+ }
+ var dur = media1.getDuration();
+ if (dur > 0) {
+ clearInterval(timerDur);
+ document.getElementById('durationValue').innerHTML = dur + ' sec';
+ }
+ }, 100);
}
- //Pause audio playback
- function pauseAudio() {
- console.log("pauseAudio()");
+ // Pause audio playback
+ function pauseAudio () {
+ console.log('pauseAudio()');
if (media1) {
media1.pause();
}
}
- //Stop audio
- function stopAudio() {
- console.log("stopAudio()");
+ // Stop audio
+ function stopAudio () {
+ console.log('stopAudio()');
if (media1) {
media1.stop();
}
@@ -634,123 +770,140 @@ exports.defineManualTests = function (contentEl, createActionButton) {
media1Timer = null;
}
- //Release audio
- function releaseAudio() {
- console.log("releaseAudio()");
+ // Release audio
+ function releaseAudio () {
+ console.log('releaseAudio()');
if (media1) {
- media1.stop(); //imlied stop of playback, resets timer
+ media1.stop(); // imlied stop of playback, resets timer
media1.release();
}
}
- //Set audio status
- function setAudioStatus(status) {
+ // Set audio status
+ function setAudioStatus (status) {
document.getElementById('statusValue').innerHTML = status;
}
- //Set audio position
- function setAudioPosition(position) {
+ // Set audio position
+ function setAudioPosition (position) {
document.getElementById('positionValue').innerHTML = position;
}
- //Seek audio
- function seekAudio(mode) {
- var time = document.getElementById("seekInput").value;
- if (time === "") {
+ // Seek audio
+ function seekAudio (mode) {
+ var time = document.getElementById('seekInput').value;
+ if (time === '') {
time = 5000;
} else {
- time = time * 1000; //we expect the input to be in seconds
+ time = time * 1000; // we expect the input to be in seconds
}
if (media1 === null) {
- console.log("seekTo requested while media1 is null");
+ console.log('seekTo requested while media1 is null');
if (audioSrc === null) {
audioSrc = defaultaudio;
}
- media1 = new Media(audioSrc,
- function () {
- console.log("seekToAudio():Audio Success");
+ media1 = new Media(
+ audioSrc,
+ function () {
+ console.log('seekToAudio():Audio Success');
},
- function (err) {
- console.log("seekAudio():Audio Error: " + err.code);
- setAudioStatus("Error: " + err.code);
+ function (err) {
+ console.log('seekAudio():Audio Error: ' + err.code);
+ setAudioStatus('Error: ' + err.code);
},
- function (status) {
- console.log("seekAudio():Audio Status: " + status);
+ function (status) {
+ console.log('seekAudio():Audio Status: ' + status);
setAudioStatus(Media.MEDIA_MSG[status]);
// If stopped, then stop getting current position
- if (Media.MEDIA_STOPPED == status) {
+ if (Media.MEDIA_STOPPED === status) {
clearInterval(media1Timer);
media1Timer = null;
- setAudioPosition("0 sec");
+ setAudioPosition('0 sec');
}
- });
+ }
+ );
}
media1.getCurrentPosition(
function (position) {
- var deltat = time;
- if (mode === "by") {
- deltat = time + position * 1000;
- }
- media1.seekTo(deltat,
- function () {
- console.log("seekAudioTo():Audio Success");
- //force an update on the position display
- updatePosition();
+ var deltat = time;
+ if (mode === 'by') {
+ deltat = time + position * 1000;
+ }
+ media1.seekTo(
+ deltat,
+ function () {
+ console.log('seekAudioTo():Audio Success');
+ // force an update on the position display
+ updatePosition();
+ },
+ function (err) {
+ console.log('seekAudioTo():Audio Error: ' + err.code);
+ }
+ );
},
- function (err) {
- console.log("seekAudioTo():Audio Error: " + err.code);
- });
- },
function (e) {
- console.log("Error getting pos=" + e);
- setAudioPosition("Error: " + e);
- });
+ console.log('Error getting pos=' + e);
+ setAudioPosition('Error: ' + e);
+ }
+ );
+ }
+
+ // set audio volume
+ function setVolume () {
+ console.log('setVolume()');
+ var volume = document.getElementById('volumeInput').value;
+ if (media1 !== null) {
+ media1.setVolume(volume);
+ }
}
- //for forced updates of position after a successful seek
+ // for forced updates of position after a successful seek
- function updatePosition() {
+ function updatePosition () {
media1.getCurrentPosition(
function (position) {
- if (position >= 0.0) {
- setAudioPosition(position + " sec");
- }
- },
+ if (position >= 0.0) {
+ setAudioPosition(position + ' sec');
+ }
+ },
function (e) {
- console.log("Error getting pos=" + e);
- setAudioPosition("Error: " + e);
- });
+ console.log('Error getting pos=' + e);
+ setAudioPosition('Error: ' + e);
+ }
+ );
}
- //-------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// Audio recorder
- //-------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
var mediaRec = null;
var recTime = 0;
- var recordSrc = "myRecording.mp3";
+ var recordSrc = 'myRecording.mp3';
- //Record audio
- function recordAudio() {
- console.log("recordAudio(), recording to " + recordSrc);
- console.log(" -- media=" + mediaRec);
+ // Record audio
+ function recordAudio () {
+ console.log('recordAudio(), recording to ' + recordSrc);
+ console.log(' -- media=' + mediaRec);
releaseAudio();
if (!mediaRec) {
- mediaRec = new Media(recordSrc,
+ mediaRec = new Media(
+ recordSrc,
function () {
- console.log("recordAudio():Audio Success");
+ console.log('recordAudio():Audio Success');
},
- function (err) {
- console.log("recordAudio():Audio Error: " + err.code);
- setAudioStatus("Error: " + err.code);
+ function (err) {
+ console.log('recordAudio():Audio Error: ' + err.code);
+ setAudioStatus('Error: ' + err.code);
},
- function (status) {
- console.log("recordAudio():Audio Status: " + status);
+ function (status) {
+ console.log('recordAudio():Audio Status: ' + status);
setAudioStatus(Media.MEDIA_MSG[status]);
- });
+ }
+ );
}
// Record audio
@@ -759,313 +912,348 @@ exports.defineManualTests = function (contentEl, createActionButton) {
// Stop recording after 10 sec
recTime = 0;
var recInterval = setInterval(function () {
- recTime = recTime + 1;
- setAudioPosition(recTime + " sec");
- if (recTime >= 10) {
- clearInterval(recInterval);
- if (mediaRec.stopAudioRecord) {
- mediaRec.stopAudioRecord();
- } else {
- mediaRec.stopRecord();
- }
- console.log("recordAudio(): stop");
+ recTime = recTime + 1;
+ setAudioPosition(recTime + ' sec');
+ if (recTime >= 10) {
+ clearInterval(recInterval);
+ if (mediaRec.stopAudioRecord) {
+ mediaRec.stopAudioRecord();
+ } else {
+ mediaRec.stopRecord();
}
- }, 1000);
+ console.log('recordAudio(): stop');
+ }
+ }, 1000);
}
- //Play back recorded audio
- function playRecording() {
+ // Play back recorded audio
+ function playRecording () {
playAudio(recordSrc);
}
- //Function to get a filename for iOS recording
- //Ensures that file doesn't exist to test CB-11380
- function getRecordSrc() {
+ // Function to get a filename for iOS recording
+ // Ensures that file doesn't exist to test CB-11380
+ function getRecordSrc () {
var noop = function () {};
- recordSrc = "cdvfile://localhost/temporary/iOSRecording.wav";
- window.resolveLocalFileSystemURL(recordSrc, function (file) {
- file.remove(function() {
- console.log("Successfully removed " + recordSrc);
- }, noop);
- }, noop);
- }
-
- //Function to create a file for BB recording
- function getRecordSrcBB() {
- var fsFail = function (error) {
- console.log("error creating file for BB recording");
- };
- var gotFile = function (file) {
- recordSrc = file.fullPath;
- };
- var gotFS = function (fileSystem) {
- fileSystem.root.getFile("BBRecording.amr", {
- create : true
- }, gotFile, fsFail);
- };
- window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, gotFS, fsFail);
- }
-
- //Function to create a file for Windows recording
- function getRecordSrcWin() {
- var fsFail = function (error) {
- console.log("error creating file for Win recording");
- };
- var gotFile = function (file) {
- recordSrc = file.name;
- };
- var gotFS = function (fileSystem) {
- fileSystem.root.getFile("WinRecording.m4a", {
- create: true
- }, gotFile, fsFail);
- };
- window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fsFail);
+ recordSrc = 'cdvfile://localhost/temporary/iOSRecording.wav';
+ window.resolveLocalFileSystemURL(
+ recordSrc,
+ function (file) {
+ file.remove(function () {
+ console.log('Successfully removed ' + recordSrc);
+ }, noop);
+ },
+ noop
+ );
}
-//Generate Dynamic Table
- function generateTable(tableId, rows, cells, elements) {
+ // Generate Dynamic Table
+ function generateTable (tableId, rows, cells, elements) {
var table = document.createElement('table');
for (var r = 0; r < rows; r++) {
var row = table.insertRow(r);
for (var c = 0; c < cells; c++) {
var cell = row.insertCell(c);
- cell.setAttribute("align", "center");
+ cell.setAttribute('align', 'center');
for (var e in elements) {
- if (elements[e].position.row == r && elements[e].position.cell == c) {
+ if (elements[e].position.row === r && elements[e].position.cell === c) {
var htmlElement = document.createElement(elements[e].tag);
var content;
- if (elements[e].content !== "") {
+ if (elements[e].content !== '') {
content = document.createTextNode(elements[e].content);
htmlElement.appendChild(content);
}
if (elements[e].type) {
htmlElement.type = elements[e].type;
}
- htmlElement.setAttribute("id", elements[e].id);
+ htmlElement.setAttribute('id', elements[e].id);
cell.appendChild(htmlElement);
}
}
}
}
- table.setAttribute("align", "center");
- table.setAttribute("id", tableId);
+ table.setAttribute('align', 'center');
+ table.setAttribute('id', tableId);
return table;
}
-//Audio && Record Elements
- var elementsResultsAudio=
- [{
- id : "statusTag",
- content : "Status:",
- tag : "div",
- position : {
- row : 0,
- cell : 0
+ // Audio && Record Elements
+ var elementsResultsAudio = [
+ {
+ id: 'statusTag',
+ content: 'Status:',
+ tag: 'div',
+ position: {
+ row: 0,
+ cell: 0
}
- }, {
- id : "statusValue",
- content : "",
- tag : "div",
- position : {
- row : 0,
- cell : 2
+ },
+ {
+ id: 'statusValue',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 0,
+ cell: 2
+ }
+ },
+ {
+ id: 'durationTag',
+ content: 'Duration:',
+ tag: 'div',
+ position: {
+ row: 1,
+ cell: 0
}
- }, {
- id : "durationTag",
- content : "Duration:",
- tag : "div",
- position : {
- row : 1,
- cell : 0
+ },
+ {
+ id: 'durationValue',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 1,
+ cell: 2
+ }
+ },
+ {
+ id: 'positionTag',
+ content: 'Position:',
+ tag: 'div',
+ position: {
+ row: 2,
+ cell: 0
}
- }, {
- id : "durationValue",
- content : "",
- tag : "div",
- position : {
- row : 1,
- cell : 2
+ },
+ {
+ id: 'positionValue',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 2,
+ cell: 2
}
- }, {
- id : "positionTag",
- content : "Position:",
- tag : "div",
- position : {
- row : 2,
- cell : 0
+ }
+ ];
+ var elementsAudio = [
+ {
+ id: 'playBtn',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 0,
+ cell: 0
}
- }, {
- id : "positionValue",
- content : "",
- tag : "div",
- position : {
- row : 2,
- cell : 2
+ },
+ {
+ id: 'pauseBtn',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 0,
+ cell: 1
}
- }],
- elementsAudio =
- [{
- id : "playBtn",
- content : "",
- tag : "div",
- position : {
- row : 0,
- cell : 0
+ },
+ {
+ id: 'stopBtn',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 1,
+ cell: 0
}
- }, {
- id : "pauseBtn",
- content : "",
- tag : "div",
- position : {
- row : 0,
- cell : 1
+ },
+ {
+ id: 'releaseBtn',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 1,
+ cell: 1
}
- }, {
- id : "stopBtn",
- content : "",
- tag : "div",
- position : {
- row : 1,
- cell : 0
+ },
+ {
+ id: 'seekByBtn',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 2,
+ cell: 0
}
- }, {
- id : "releaseBtn",
- content : "",
- tag : "div",
- position : {
- row : 1,
- cell : 1
+ },
+ {
+ id: 'seekToBtn',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 2,
+ cell: 1
}
- }, {
- id : "seekByBtn",
- content : "",
- tag : "div",
- position : {
- row : 2,
- cell : 0
+ },
+ {
+ id: 'seekInput',
+ content: '',
+ tag: 'input',
+ type: 'number',
+ position: {
+ row: 2,
+ cell: 2
}
- }, {
- id : "seekToBtn",
- content : "",
- tag : "div",
- position : {
- row : 2,
- cell : 1
+ },
+ {
+ id: 'halfSpeedBtn',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 0,
+ cell: 2
}
- }, {
- id : "seekInput",
- content : "",
- tag : "input",
- type : "number",
- position : {
- row : 2,
- cell : 2
+ },
+ {
+ id: 'setVolumeBtn',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 3,
+ cell: 0
}
- }, {
- id: "halfSpeedBtn",
- content:"",
- tag:"div",
- position:{
- row:0,
- cell:2
+ },
+ {
+ id: 'volumeInput',
+ tag: 'input',
+ type: 'text',
+ position: {
+ row: 3,
+ cell: 1
}
}
- ],
- elementsRecord =
- [{
- id : "recordbtn",
- content : "",
- tag : "div",
- position : {
- row : 1,
- cell : 0
+ ];
+ var elementsRecord = [
+ {
+ id: 'recordbtn',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 1,
+ cell: 0
}
- }, {
- id : "recordplayBtn",
- content : "",
- tag : "div",
- position : {
- row : 1,
- cell : 1
+ },
+ {
+ id: 'recordplayBtn',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 1,
+ cell: 1
}
- }, {
- id : "recordpauseBtn",
- content : "",
- tag : "div",
- position : {
- row : 2,
- cell : 0
+ },
+ {
+ id: 'recordpauseBtn',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 2,
+ cell: 0
}
- }, {
- id : "recordstopBtn",
- content : "",
- tag : "div",
- position : {
- row : 2,
- cell : 1
+ },
+ {
+ id: 'recordstopBtn',
+ content: '',
+ tag: 'div',
+ position: {
+ row: 2,
+ cell: 1
}
}
];
- //Title audio results
+ // Title audio results
var div = document.createElement('h2');
div.appendChild(document.createTextNode('Audio'));
- div.setAttribute("align", "center");
+ div.setAttribute('align', 'center');
contentEl.appendChild(div);
- //Generate and add results table
+ // Generate and add results table
contentEl.appendChild(generateTable('info', 3, 3, elementsResultsAudio));
- //Title audio actions
+ // Title audio actions
div = document.createElement('h2');
div.appendChild(document.createTextNode('Actions'));
- div.setAttribute("align", "center");
+ div.setAttribute('align', 'center');
contentEl.appendChild(div);
- //Generate and add buttons table
- contentEl.appendChild(generateTable('audioActions', 3, 3, elementsAudio));
- createActionButton('Play', function () {
- playAudio();
- }, 'playBtn');
- createActionButton('Pause', function () {
- pauseAudio();
- }, 'pauseBtn');
- createActionButton('HalfSpeed', function() {
- if(halfSpeedBtn.firstChild.firstChild.innerText == 'HalfSpeed') {
- halfSpeedBtn.firstChild.firstChild.innerText = 'FullSpeed';
- media1.setRate(0.5);
- }
- else if(halfSpeedBtn.firstChild.firstChild.innerText == 'FullSpeed') {
- halfSpeedBtn.firstChild.firstChild.innerText = 'DoubleSpeed';
- media1.setRate(1.0);
- }
- else {
- halfSpeedBtn.firstChild.firstChild.innerText = 'HalfSpeed';
- media1.setRate(2.0);
- }
- }, 'halfSpeedBtn');
- createActionButton('Stop', function () {
- stopAudio();
- }, 'stopBtn');
- createActionButton('Release', function () {
- releaseAudio();
- }, 'releaseBtn');
- createActionButton('Seek By', function () {
- seekAudio('by');
- }, 'seekByBtn');
- createActionButton('Seek To', function () {
- seekAudio('to');
- }, 'seekToBtn');
- //get Special path to record if iOS || Blackberry
- if (cordova.platformId === 'ios')
+ // Generate and add buttons table
+ contentEl.appendChild(generateTable('audioActions', 4, 3, elementsAudio));
+ createActionButton(
+ 'Play',
+ function () {
+ playAudio();
+ },
+ 'playBtn'
+ );
+ createActionButton(
+ 'Pause',
+ function () {
+ pauseAudio();
+ },
+ 'pauseBtn'
+ );
+ createActionButton(
+ 'HalfSpeed',
+ function () {
+ if (halfSpeedBtn.firstChild.firstChild.innerText === 'HalfSpeed') {
+ halfSpeedBtn.firstChild.firstChild.innerText = 'FullSpeed';
+ media1.setRate(0.5);
+ } else if (halfSpeedBtn.firstChild.firstChild.innerText === 'FullSpeed') {
+ halfSpeedBtn.firstChild.firstChild.innerText = 'DoubleSpeed';
+ media1.setRate(1.0);
+ } else {
+ halfSpeedBtn.firstChild.firstChild.innerText = 'HalfSpeed';
+ media1.setRate(2.0);
+ }
+ },
+ 'halfSpeedBtn'
+ );
+ createActionButton(
+ 'Stop',
+ function () {
+ stopAudio();
+ },
+ 'stopBtn'
+ );
+ createActionButton(
+ 'Release',
+ function () {
+ releaseAudio();
+ },
+ 'releaseBtn'
+ );
+ createActionButton(
+ 'Seek By',
+ function () {
+ seekAudio('by');
+ },
+ 'seekByBtn'
+ );
+ createActionButton(
+ 'Seek To',
+ function () {
+ seekAudio('to');
+ },
+ 'seekToBtn'
+ );
+ createActionButton(
+ 'Set volume',
+ function () {
+ setVolume();
+ },
+ 'setVolumeBtn'
+ );
+ // get Special path to record if iOS
+ if (cordova.platformId === 'ios') {
getRecordSrc();
- else if (cordova.platformId === 'blackberry')
- getRecordSrcBB();
- else if (cordova.platformId === 'windows' || cordova.platformId === 'windows8')
- getRecordSrcWin();
-
- //testing process and details
- function addItemToList(_list, _text)
- {
+ }
+
+ // testing process and details
+ function addItemToList (_list, _text) {
var item = document.createElement('li');
item.appendChild(document.createTextNode(_text));
_list.appendChild(item);
@@ -1076,8 +1264,14 @@ exports.defineManualTests = function (contentEl, createActionButton) {
contentEl.appendChild(div);
var list = document.createElement('ol');
- addItemToList(list, 'Press play - Will start playing audio. Status: Running, Duration: 61.333 sec, Position: Current position of audio track');
- addItemToList(list, 'Press pause - Will pause the audio. Status: Paused, Duration: 61.333 sec, Position: Position where track was paused');
+ addItemToList(
+ list,
+ 'Press play - Will start playing audio. Status: Running, Duration: 61.333 sec, Position: Current position of audio track'
+ );
+ addItemToList(
+ list,
+ 'Press pause - Will pause the audio. Status: Paused, Duration: 61.333 sec, Position: Position where track was paused'
+ );
addItemToList(list, 'Press play - Will begin playing where track left off from the pause');
addItemToList(list, 'Press stop - Will stop the audio. Status: Stopped, Duration: 61.333 sec, Position: 0 sec');
addItemToList(list, 'Press play - Will begin playing the audio track from the beginning');
@@ -1093,46 +1287,80 @@ exports.defineManualTests = function (contentEl, createActionButton) {
addItemToList(list, 'Press play, let play past 10 seconds then press seek to - should jump back to position 5 sec');
div = document.createElement('div');
- div.setAttribute("style", "background:#B0C4DE;border:1px solid #FFA07A;margin:15px 6px 0px;min-width:295px;max-width:97%;padding:4px 0px 2px 10px;min-height:160px;max-height:200px;overflow:auto");
+ div.setAttribute(
+ 'style',
+ 'background:#B0C4DE;border:1px solid #FFA07A;margin:15px 6px 0px;min-width:295px;max-width:97%;padding:4px 0px 2px 10px;min-height:160px;max-height:200px;overflow:auto'
+ );
div.appendChild(list);
contentEl.appendChild(div);
- //Title Record Audio
+ // Title Record Audio
div = document.createElement('h2');
div.appendChild(document.createTextNode('Record Audio'));
- div.setAttribute("align", "center");
+ div.setAttribute('align', 'center');
contentEl.appendChild(div);
- //Generate and add Record buttons table
+ // Generate and add Record buttons table
contentEl.appendChild(generateTable('recordContent', 3, 3, elementsRecord));
- createActionButton('Record Audio \n 10 sec', function () {
- recordAudio();
- }, 'recordbtn');
- createActionButton('Play', function () {
- playRecording();
- }, 'recordplayBtn');
- createActionButton('Pause', function () {
- pauseAudio();
- }, 'recordpauseBtn');
- createActionButton('Stop', function () {
- stopAudio();
- }, 'recordstopBtn');
-
- //testing process and details
+ createActionButton(
+ 'Record Audio \n 10 sec',
+ function () {
+ recordAudio();
+ },
+ 'recordbtn'
+ );
+ createActionButton(
+ 'Play',
+ function () {
+ playRecording();
+ },
+ 'recordplayBtn'
+ );
+ createActionButton(
+ 'Pause',
+ function () {
+ pauseAudio();
+ },
+ 'recordpauseBtn'
+ );
+ createActionButton(
+ 'Stop',
+ function () {
+ stopAudio();
+ },
+ 'recordstopBtn'
+ );
+
+ // testing process and details
div = document.createElement('h4');
div.appendChild(document.createTextNode('Recommended Test Procedure'));
contentEl.appendChild(div);
list = document.createElement('ol');
- addItemToList(list, 'Press Record Audio 10 sec - Will start recording audio for 10 seconds. Status: Running, Position: number of seconds recorded (will stop at 10)');
+ addItemToList(
+ list,
+ 'Press Record Audio 10 sec - Will start recording audio for 10 seconds. Status: Running, Position: number of seconds recorded (will stop at 10)'
+ );
addItemToList(list, 'Status will change to Stopped when finished recording');
- addItemToList(list, 'Press play - Will begin playing the recording. Status: Running, Duration: # of seconds of recording, Position: Current position of recording');
- addItemToList(list, 'Press stop - Will stop playing the recording. Status: Stopped, Duration: # of seconds of recording, Position: 0 sec');
+ addItemToList(
+ list,
+ 'Press play - Will begin playing the recording. Status: Running, Duration: # of seconds of recording, Position: Current position of recording'
+ );
+ addItemToList(
+ list,
+ 'Press stop - Will stop playing the recording. Status: Stopped, Duration: # of seconds of recording, Position: 0 sec'
+ );
addItemToList(list, 'Press play - Will begin playing the recording from the beginning');
- addItemToList(list, 'Press pause - Will pause the playback of the recording. Status: Paused, Duration: # of seconds of recording, Position: Position where recording was paused');
+ addItemToList(
+ list,
+ 'Press pause - Will pause the playback of the recording. Status: Paused, Duration: # of seconds of recording, Position: Position where recording was paused'
+ );
addItemToList(list, 'Press play - Will begin playing the recording from where it was paused');
div = document.createElement('div');
- div.setAttribute("style", "background:#B0C4DE;border:1px solid #FFA07A;margin:15px 6px 0px;min-width:295px;max-width:97%;padding:4px 0px 2px 10px;min-height:160px;max-height:200px;overflow:auto");
+ div.setAttribute(
+ 'style',
+ 'background:#B0C4DE;border:1px solid #FFA07A;margin:15px 6px 0px;min-width:295px;max-width:97%;padding:4px 0px 2px 10px;min-height:160px;max-height:200px;overflow:auto'
+ );
div.appendChild(list);
contentEl.appendChild(div);
};
diff --git a/types/index.d.ts b/types/index.d.ts
new file mode 100644
index 000000000..18f449644
--- /dev/null
+++ b/types/index.d.ts
@@ -0,0 +1,92 @@
+// Type definitions for Apache Cordova Media plugin
+// Project: https://github.com/apache/cordova-plugin-media
+// Definitions by: Microsoft Open Technologies Inc
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+//
+// Copyright (c) Microsoft Open Technologies Inc
+// Licensed under the MIT license
+
+declare var Media: {
+ new (
+ src: string,
+ mediaSuccess: () => void,
+ mediaError?: (error: MediaError) => any,
+ mediaStatus?: (status: number) => void): Media;
+ //Media statuses
+ MEDIA_NONE: number;
+ MEDIA_STARTING: number;
+ MEDIA_RUNNING: number;
+ MEDIA_PAUSED: number;
+ MEDIA_STOPPED: number
+};
+
+/**
+ * This plugin provides the ability to record and play back audio files on a device.
+ * NOTE: The current implementation does not adhere to a W3C specification for media capture,
+ * and is provided for convenience only. A future implementation will adhere to the latest
+ * W3C specification and may deprecate the current APIs.
+ */
+interface Media {
+ /**
+ * Returns the current amplitude within an audio file.
+ * @param mediaSuccess The callback that is passed the current amplitude (0.0 - 1.0).
+ * @param mediaError The callback to execute if an error occurs.
+ */
+ getCurrentAmplitude(
+ mediaSuccess: (amplitude: number) => void,
+ mediaError?: (error: MediaError) => void): void;
+ /**
+ * Returns the current position within an audio file. Also updates the Media object's position parameter.
+ * @param mediaSuccess The callback that is passed the current position in seconds.
+ * @param mediaError The callback to execute if an error occurs.
+ */
+ getCurrentPosition(
+ mediaSuccess: (position: number) => void,
+ mediaError?: (error: MediaError) => void): void;
+ /** Returns the duration of an audio file in seconds. If the duration is unknown, it returns a value of -1. */
+ getDuration(): number;
+ /**
+ * Starts or resumes playing an audio file.
+ * @param iosPlayOptions: iOS options quirks
+ */
+ play(iosPlayOptions?: IosPlayOptions): void;
+ /** Pauses playing an audio file. */
+ pause(): void;
+ /**
+ * Releases the underlying operating system's audio resources. This is particularly important
+ * for Android, since there are a finite amount of OpenCore instances for media playback.
+ * Applications should call the release function for any Media resource that is no longer needed.
+ */
+ release(): void;
+ /**
+ * Sets the current position within an audio file.
+ * @param position Position in milliseconds.
+ */
+ seekTo(position: number): void;
+ /**
+ * Set the volume for an audio file.
+ * @param volume The volume to set for playback. The value must be within the range of 0.0 to 1.0.
+ */
+ setVolume(volume: number): void;
+ /** Starts recording an audio file. */
+ startRecord(): void;
+ /** Stops recording an audio file. */
+ stopRecord(): void;
+ /** Stops playing an audio file. */
+ stop(): void;
+ /**
+ * The position within the audio playback, in seconds.
+ * Not automatically updated during play; call getCurrentPosition to update.
+ */
+ position: number;
+ /** The duration of the media, in seconds. */
+ duration: number;
+}
+/**
+ * iOS optional parameters for media.play
+ * See https://github.com/apache/cordova-plugin-media#ios-quirks
+ */
+interface IosPlayOptions {
+ numberOfLoops?: number;
+ playAudioWhenScreenIsLocked?: boolean;
+}
diff --git a/www/Media.js b/www/Media.js
index 5806b9f6f..8d5ae6555 100644
--- a/www/Media.js
+++ b/www/Media.js
@@ -17,11 +17,13 @@
* specific language governing permissions and limitations
* under the License.
*
-*/
+ */
+
+/* global cordova */
-var argscheck = require('cordova/argscheck'),
- utils = require('cordova/utils'),
- exec = require('cordova/exec');
+var argscheck = require('cordova/argscheck');
+var utils = require('cordova/utils');
+var exec = require('cordova/exec');
var mediaObjects = {};
@@ -35,9 +37,13 @@ var mediaObjects = {};
* @param errorCallback The callback to be called if there is an error.
* errorCallback(int errorCode) - OPTIONAL
* @param statusCallback The callback to be called when media status has changed.
- * statusCallback(int statusCode) - OPTIONAL
+ * statusCallback(int statusCode) - OPTIONAL
+ *
+ * @param durationUpdateCallback The callback to be called when the duration updates.
+ * durationUpdateCallback(float duration) - OPTIONAL
+ *
*/
-var Media = function(src, successCallback, errorCallback, statusCallback) {
+var Media = function (src, successCallback, errorCallback, statusCallback, durationUpdateCallback) {
argscheck.checkArgs('sFFF', 'Media', arguments);
this.id = utils.createUUID();
mediaObjects[this.id] = this;
@@ -45,9 +51,10 @@ var Media = function(src, successCallback, errorCallback, statusCallback) {
this.successCallback = successCallback;
this.errorCallback = errorCallback;
this.statusCallback = statusCallback;
+ this.durationUpdateCallback = durationUpdateCallback;
this._duration = -1;
this._position = -1;
- exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);
+ exec(null, this.errorCallback, 'Media', 'create', [this.id, this.src]);
};
// Media messages
@@ -62,45 +69,57 @@ Media.MEDIA_STARTING = 1;
Media.MEDIA_RUNNING = 2;
Media.MEDIA_PAUSED = 3;
Media.MEDIA_STOPPED = 4;
-Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"];
+Media.MEDIA_MSG = ['None', 'Starting', 'Running', 'Paused', 'Stopped'];
// "static" function to return existing objs.
-Media.get = function(id) {
+Media.get = function (id) {
return mediaObjects[id];
};
/**
* Start or resume playing audio file.
*/
-Media.prototype.play = function(options) {
- exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]);
+Media.prototype.play = function (options) {
+ exec(null, null, 'Media', 'startPlayingAudio', [this.id, this.src, options]);
};
/**
* Stop playing audio file.
*/
-Media.prototype.stop = function() {
+Media.prototype.stop = function () {
var me = this;
- exec(function() {
- me._position = 0;
- }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]);
+ exec(
+ function () {
+ me._position = 0;
+ },
+ this.errorCallback,
+ 'Media',
+ 'stopPlayingAudio',
+ [this.id]
+ );
};
/**
* Seek or jump to a new time in the track..
*/
-Media.prototype.seekTo = function(milliseconds) {
+Media.prototype.seekTo = function (milliseconds) {
var me = this;
- exec(function(p) {
- me._position = p;
- }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]);
+ exec(
+ function (p) {
+ me._position = p;
+ },
+ this.errorCallback,
+ 'Media',
+ 'seekToAudio',
+ [this.id, milliseconds]
+ );
};
/**
* Pause playing audio file.
*/
-Media.prototype.pause = function() {
- exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]);
+Media.prototype.pause = function () {
+ exec(null, this.errorCallback, 'Media', 'pausePlayingAudio', [this.id]);
};
/**
@@ -109,69 +128,84 @@ Media.prototype.pause = function() {
*
* @return duration or -1 if not known.
*/
-Media.prototype.getDuration = function() {
+Media.prototype.getDuration = function () {
return this._duration;
};
/**
* Get position of audio.
*/
-Media.prototype.getCurrentPosition = function(success, fail) {
+Media.prototype.getCurrentPosition = function (success, fail) {
var me = this;
- exec(function(p) {
- me._position = p;
- success(p);
- }, fail, "Media", "getCurrentPositionAudio", [this.id]);
+ exec(
+ function (p) {
+ me._position = p;
+ success(p);
+ },
+ fail,
+ 'Media',
+ 'getCurrentPositionAudio',
+ [this.id]
+ );
};
/**
* Start recording audio file.
*/
-Media.prototype.startRecord = function() {
- exec(null, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]);
+Media.prototype.startRecord = function () {
+ exec(null, this.errorCallback, 'Media', 'startRecordingAudio', [this.id, this.src]);
};
/**
* Stop recording audio file.
*/
-Media.prototype.stopRecord = function() {
- exec(null, this.errorCallback, "Media", "stopRecordingAudio", [this.id]);
+Media.prototype.stopRecord = function () {
+ exec(null, this.errorCallback, 'Media', 'stopRecordingAudio', [this.id]);
};
/**
* Pause recording audio file.
*/
-Media.prototype.pauseRecord = function() {
- exec(null, this.errorCallback, "Media", "pauseRecordingAudio", [this.id]);
+Media.prototype.pauseRecord = function () {
+ exec(null, this.errorCallback, 'Media', 'pauseRecordingAudio', [this.id]);
};
/**
-* Resume recording audio file.
-*/
-Media.prototype.resumeRecord = function() {
- exec(null, this.errorCallback, "Media", "resumeRecordingAudio", [this.id]);
+ * Resume recording audio file.
+ */
+Media.prototype.resumeRecord = function () {
+ exec(null, this.errorCallback, 'Media', 'resumeRecordingAudio', [this.id]);
};
/**
* Release the resources.
*/
-Media.prototype.release = function() {
- exec(null, this.errorCallback, "Media", "release", [this.id]);
+Media.prototype.release = function () {
+ var me = this;
+ exec(
+ function () {
+ delete mediaObjects[me.id];
+ },
+ this.errorCallback,
+ 'Media',
+ 'release',
+ [this.id]
+ );
};
/**
* Adjust the volume.
*/
-Media.prototype.setVolume = function(volume) {
- exec(null, null, "Media", "setVolume", [this.id, volume]);
+Media.prototype.setVolume = function (volume) {
+ exec(null, null, 'Media', 'setVolume', [this.id, volume]);
};
/**
* Adjust the playback rate.
*/
-Media.prototype.setRate = function(rate) {
- if (cordova.platformId === 'ios'){
- exec(null, null, "Media", "setRate", [this.id, rate]);
+Media.prototype.setRate = function (rate) {
+ if (cordova.platformId === 'ios' || cordova.platformId === 'android') {
+ exec(null, null, 'Media', 'setRate', [this.id, rate]);
} else {
console.warn('media.setRate method is currently not supported for', cordova.platformId, 'platform.');
}
@@ -180,10 +214,16 @@ Media.prototype.setRate = function(rate) {
/**
* Get amplitude of audio.
*/
-Media.prototype.getCurrentAmplitude = function(success, fail) {
- exec(function(p) {
- success(p);
- }, fail, "Media", "getCurrentAmplitudeAudio", [this.id]);
+Media.prototype.getCurrentAmplitude = function (success, fail) {
+ exec(
+ function (p) {
+ success(p);
+ },
+ fail,
+ 'Media',
+ 'getCurrentAmplitudeAudio',
+ [this.id]
+ );
};
/**
@@ -194,63 +234,63 @@ Media.prototype.getCurrentAmplitude = function(success, fail) {
* @param msgType The 'type' of update this is
* @param value Use of value is determined by the msgType
*/
-Media.onStatus = function(id, msgType, value) {
-
+Media.onStatus = function (id, msgType, value) {
var media = mediaObjects[id];
if (media) {
- switch(msgType) {
- case Media.MEDIA_STATE :
- if (media.statusCallback) {
- media.statusCallback(value);
- }
- if (value == Media.MEDIA_STOPPED) {
- if (media.successCallback) {
- media.successCallback();
- }
- }
- break;
- case Media.MEDIA_DURATION :
- media._duration = value;
- break;
- case Media.MEDIA_ERROR :
- if (media.errorCallback) {
- media.errorCallback(value);
+ switch (msgType) {
+ case Media.MEDIA_STATE:
+ if (media.statusCallback) {
+ media.statusCallback(value);
+ }
+ if (value === Media.MEDIA_STOPPED) {
+ if (media.successCallback) {
+ media.successCallback();
}
- break;
- case Media.MEDIA_POSITION :
- media._position = Number(value);
- break;
- default :
- if (console.error) {
- console.error("Unhandled Media.onStatus :: " + msgType);
- }
- break;
+ }
+ break;
+ case Media.MEDIA_DURATION:
+ media._duration = value;
+ if (media.durationUpdateCallback) {
+ media.durationUpdateCallback(value);
+ }
+ break;
+ case Media.MEDIA_ERROR:
+ if (media.errorCallback) {
+ media.errorCallback(value);
+ }
+ break;
+ case Media.MEDIA_POSITION:
+ media._position = Number(value);
+ break;
+ default:
+ if (console.error) {
+ console.error('Unhandled Media.onStatus :: ' + msgType);
+ }
+ break;
}
} else if (console.error) {
- console.error("Received Media.onStatus callback for unknown media :: " + id);
+ console.error('Received Media.onStatus callback for unknown media :: ' + id);
}
-
};
module.exports = Media;
-function onMessageFromNative(msg) {
- if (msg.action == 'status') {
+function onMessageFromNative (msg) {
+ if (msg.action === 'status') {
Media.onStatus(msg.status.id, msg.status.msgType, msg.status.value);
} else {
throw new Error('Unknown media action' + msg.action);
}
}
-if (cordova.platformId === 'android' || cordova.platformId === 'amazon-fireos' || cordova.platformId === 'windowsphone') {
-
+if (cordova.platformId === 'android') {
var channel = require('cordova/channel');
channel.createSticky('onMediaPluginReady');
channel.waitForInitialization('onMediaPluginReady');
- channel.onCordovaReady.subscribe(function() {
+ channel.onCordovaReady.subscribe(function () {
exec(onMessageFromNative, undefined, 'Media', 'messageChannel', []);
channel.initializationComplete('onMediaPluginReady');
});
diff --git a/www/MediaError.js b/www/MediaError.js
index 38002ac5e..1117e9e01 100644
--- a/www/MediaError.js
+++ b/www/MediaError.js
@@ -17,11 +17,11 @@
* specific language governing permissions and limitations
* under the License.
*
-*/
+ */
/**
* This class contains information about any Media errors.
-*/
+ */
/*
According to :: http://dev.w3.org/html5/spec-author-view/video.html#mediaerror
We should never be creating these objects, we should just implement the interface
@@ -33,20 +33,19 @@ we should simply use a literal :
errorCallbackFunction( {'code':3} );
*/
- var _MediaError = window.MediaError;
-
+var _MediaError = window.MediaError;
-if(!_MediaError) {
- window.MediaError = _MediaError = function(code, msg) {
- this.code = (typeof code != 'undefined') ? code : null;
- this.message = msg || ""; // message is NON-standard! do not use!
+if (!_MediaError) {
+ window.MediaError = _MediaError = function (code, msg) {
+ this.code = typeof code !== 'undefined' ? code : null;
+ this.message = msg || ''; // message is NON-standard! do not use!
};
}
-_MediaError.MEDIA_ERR_NONE_ACTIVE = _MediaError.MEDIA_ERR_NONE_ACTIVE || 0;
-_MediaError.MEDIA_ERR_ABORTED = _MediaError.MEDIA_ERR_ABORTED || 1;
-_MediaError.MEDIA_ERR_NETWORK = _MediaError.MEDIA_ERR_NETWORK || 2;
-_MediaError.MEDIA_ERR_DECODE = _MediaError.MEDIA_ERR_DECODE || 3;
+_MediaError.MEDIA_ERR_NONE_ACTIVE = _MediaError.MEDIA_ERR_NONE_ACTIVE || 0;
+_MediaError.MEDIA_ERR_ABORTED = _MediaError.MEDIA_ERR_ABORTED || 1;
+_MediaError.MEDIA_ERR_NETWORK = _MediaError.MEDIA_ERR_NETWORK || 2;
+_MediaError.MEDIA_ERR_DECODE = _MediaError.MEDIA_ERR_DECODE || 3;
_MediaError.MEDIA_ERR_NONE_SUPPORTED = _MediaError.MEDIA_ERR_NONE_SUPPORTED || 4;
// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below.
// as defined by http://dev.w3.org/html5/spec-author-view/video.html#error-codes
diff --git a/www/browser/Media.js b/www/browser/Media.js
index 2e3da7f16..6923ef9c5 100644
--- a/www/browser/Media.js
+++ b/www/browser/Media.js
@@ -17,12 +17,12 @@
* specific language governing permissions and limitations
* under the License.
*
-*/
+ */
/* global MediaError */
-var argscheck = require('cordova/argscheck'),
- utils = require('cordova/utils');
+var argscheck = require('cordova/argscheck');
+var utils = require('cordova/utils');
var mediaObjects = {};
@@ -38,7 +38,7 @@ var mediaObjects = {};
* @param statusCallback The callback to be called when media status has changed.
* statusCallback(int statusCode) - OPTIONAL
*/
-var Media = function(src, successCallback, errorCallback, statusCallback) {
+var Media = function (src, successCallback, errorCallback, statusCallback) {
argscheck.checkArgs('SFFF', 'Media', arguments);
this.id = utils.createUUID();
mediaObjects[this.id] = this;
@@ -49,24 +49,24 @@ var Media = function(src, successCallback, errorCallback, statusCallback) {
this._duration = -1;
this._position = -1;
- Media.onStatus(this.id, Media.MEDIA_STATE, Media.MEDIA_STARTING);
-
try {
this.node = createNode(this);
} catch (err) {
- Media.onStatus(this.id, Media.MEDIA_ERROR, { code: MediaError.MEDIA_ERR_ABORTED });
+ Media.onStatus(this.id, Media.MEDIA_ERROR, {
+ code: MediaError.MEDIA_ERR_ABORTED
+ });
}
};
/**
* Creates new Audio node and with necessary event listeners attached
* @param {Media} media Media object
- * @return {Audio} Audio element
+ * @return {Audio} Audio element
*/
function createNode (media) {
var node = new Audio();
- node.onloadstart = function () {
+ node.onplay = function () {
Media.onStatus(media.id, Media.MEDIA_STATE, Media.MEDIA_STARTING);
};
@@ -80,9 +80,7 @@ function createNode (media) {
node.onerror = function (e) {
// Due to media.spec.15 It should return MediaError for bad filename
- var err = e.target.error.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED ?
- { code: MediaError.MEDIA_ERR_ABORTED } :
- e.target.error;
+ var err = e.target.error.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED ? { code: MediaError.MEDIA_ERR_ABORTED } : e.target.error;
Media.onStatus(media.id, Media.MEDIA_ERROR, err);
};
@@ -110,19 +108,20 @@ Media.MEDIA_STARTING = 1;
Media.MEDIA_RUNNING = 2;
Media.MEDIA_PAUSED = 3;
Media.MEDIA_STOPPED = 4;
-Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"];
+Media.MEDIA_MSG = ['None', 'Starting', 'Running', 'Paused', 'Stopped'];
/**
* Start or resume playing audio file.
*/
-Media.prototype.play = function() {
-
+Media.prototype.play = function () {
// if Media was released, then node will be null and we need to create it again
if (!this.node) {
try {
this.node = createNode(this);
} catch (err) {
- Media.onStatus(this.id, Media.MEDIA_ERROR, { code: MediaError.MEDIA_ERR_ABORTED });
+ Media.onStatus(this.id, Media.MEDIA_ERROR, {
+ code: MediaError.MEDIA_ERR_ABORTED
+ });
}
}
@@ -132,7 +131,7 @@ Media.prototype.play = function() {
/**
* Stop playing audio file.
*/
-Media.prototype.stop = function() {
+Media.prototype.stop = function () {
try {
this.pause();
this.seekTo(0);
@@ -145,7 +144,7 @@ Media.prototype.stop = function() {
/**
* Seek or jump to a new time in the track..
*/
-Media.prototype.seekTo = function(milliseconds) {
+Media.prototype.seekTo = function (milliseconds) {
try {
this.node.currentTime = milliseconds / 1000;
} catch (err) {
@@ -156,13 +155,14 @@ Media.prototype.seekTo = function(milliseconds) {
/**
* Pause playing audio file.
*/
-Media.prototype.pause = function() {
+Media.prototype.pause = function () {
try {
this.node.pause();
Media.onStatus(this.id, Media.MEDIA_STATE, Media.MEDIA_PAUSED);
} catch (err) {
Media.onStatus(this.id, Media.MEDIA_ERROR, err);
- }};
+ }
+};
/**
* Get duration of an audio file.
@@ -170,14 +170,14 @@ Media.prototype.pause = function() {
*
* @return duration or -1 if not known.
*/
-Media.prototype.getDuration = function() {
+Media.prototype.getDuration = function () {
return this._duration;
};
/**
* Get position of audio.
*/
-Media.prototype.getCurrentPosition = function(success, fail) {
+Media.prototype.getCurrentPosition = function (success, fail) {
try {
var p = this.node.currentTime;
Media.onStatus(this.id, Media.MEDIA_POSITION, p);
@@ -190,31 +190,60 @@ Media.prototype.getCurrentPosition = function(success, fail) {
/**
* Start recording audio file.
*/
-Media.prototype.startRecord = function() {
- Media.onStatus(this.id, Media.MEDIA_ERROR, "Not supported");
+Media.prototype.startRecord = function () {
+ Media.onStatus(this.id, Media.MEDIA_ERROR, 'Not supported');
};
/**
* Stop recording audio file.
*/
-Media.prototype.stopRecord = function() {
- Media.onStatus(this.id, Media.MEDIA_ERROR, "Not supported");
+Media.prototype.stopRecord = function () {
+ Media.onStatus(this.id, Media.MEDIA_ERROR, 'Not supported');
+};
+
+/**
+ * Pause recording audio file.
+ */
+Media.prototype.pauseRecord = function () {
+ Media.onStatus(this.id, Media.MEDIA_ERROR, 'Not supported');
+};
+
+/**
+ * Returns the current amplitude of the current recording.
+ */
+Media.prototype.getCurrentAmplitude = function () {
+ Media.onStatus(this.id, Media.MEDIA_ERROR, 'Not supported');
+};
+
+/**
+ * Resume recording an audio file.
+ */
+Media.prototype.resumeRecord = function () {
+ Media.onStatus(this.id, Media.MEDIA_ERROR, 'Not supported');
+};
+
+/**
+ * Set rate of an autio file.
+ */
+Media.prototype.setRate = function () {
+ Media.onStatus(this.id, Media.MEDIA_ERROR, 'Not supported');
};
/**
* Release the resources.
*/
-Media.prototype.release = function() {
+Media.prototype.release = function () {
try {
delete this.node;
} catch (err) {
Media.onStatus(this.id, Media.MEDIA_ERROR, err);
- }};
+ }
+};
/**
* Adjust the volume.
*/
-Media.prototype.setVolume = function(volume) {
+Media.prototype.setVolume = function (volume) {
this.node.volume = volume;
};
@@ -226,41 +255,40 @@ Media.prototype.setVolume = function(volume) {
* @param msgType The 'type' of update this is
* @param value Use of value is determined by the msgType
*/
-Media.onStatus = function(id, msgType, value) {
-
+Media.onStatus = function (id, msgType, value) {
var media = mediaObjects[id];
if (media) {
- switch(msgType) {
- case Media.MEDIA_STATE :
- if (media.statusCallback) {
- media.statusCallback(value);
- }
- if (value === Media.MEDIA_STOPPED) {
- if (media.successCallback) {
- media.successCallback();
- }
- }
- break;
- case Media.MEDIA_DURATION :
- media._duration = value;
- break;
- case Media.MEDIA_ERROR :
- if (media.errorCallback) {
- media.errorCallback(value);
- }
- break;
- case Media.MEDIA_POSITION :
- media._position = Number(value);
- break;
- default :
- if (console.error) {
- console.error("Unhandled Media.onStatus :: " + msgType);
+ switch (msgType) {
+ case Media.MEDIA_STATE:
+ if (media.statusCallback) {
+ media.statusCallback(value);
+ }
+ if (value === Media.MEDIA_STOPPED) {
+ if (media.successCallback) {
+ media.successCallback();
}
- break;
+ }
+ break;
+ case Media.MEDIA_DURATION:
+ media._duration = value;
+ break;
+ case Media.MEDIA_ERROR:
+ if (media.errorCallback) {
+ media.errorCallback(value);
+ }
+ break;
+ case Media.MEDIA_POSITION:
+ media._position = Number(value);
+ break;
+ default:
+ if (console.error) {
+ console.error('Unhandled Media.onStatus :: ' + msgType);
+ }
+ break;
}
} else if (console.error) {
- console.error("Received Media.onStatus callback for unknown media :: " + id);
+ console.error('Received Media.onStatus callback for unknown media :: ' + id);
}
};